Open yizihan opened 6 years ago
Promise里面保存着未来才会结束的事件(通常是一个异步操作)的结果。 Promise是一个对象,从它可以获取异步操作的消息。 Promise是一个构造函数,用来生成Promise实例。 Promise新建之后就会立即执行。
const promise = new Promise((resolve, reject) => { if(/*异步操作成功*/) { // 将Promise对象的状态从“未完成”变为“成功”,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去; resolve(value); } else { // 将Promise对象的状态从“未完成”变为“失败”,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去; reject(error); } }); // Promise生成实例以后,可以用then方法分别指定resolved状态和rejected状态的回调函数 promise.then(function() { // success }, function() { // failure });
用Promise实现Ajax
const getJSON = function(url) { // 返回Promise return new Promise((resolve, reject) => { // 新建XML请求实例 const client = new XMLHttpRequest; // 设置请求头 client.setRequestHeader('Accept', 'application/json'); // 设置接收数据格式 client.responseType = 'json'; // 开启请求 client.open('GET', url); // 监听请求返回的内容 client.onreadystatechange = function() { if(this.readyState !== 4) return; if(this.status === 200) { // 将成功得到数据resolve resolve(this.response); } else { // 抛出错误状态码 reject(new Error(this.statusText)); } }; client.send(); }) } getJSON('/post.json').then((json) => { // Promise状态完成后执行 console.log('Contents: ' + json); }, (error) => { // Promise状态失败后执行 console.log('Error: ' + error); })
为Promise实例添加状态改变时的回调函数。
第一个参数是resolved状态的回调函数;第二个参数是rejected状态的回调函数。
then方法返回的是一个新的Promise实例,因此可以采用链式写法。
getJSON('/post.json').then(function(post){ return getJSON(post.commitURL); }).then(function(comments){ console.log('resolved: ' + comments); }, function(err) { console.log('rejected: ' + err); })
用于指定发生错误时的回调函数。
getJSON('/posts.json').then(posts => { // ... }).catch(error => { console.log('Error: ' + error); })
指定不管Promise对象最后状态如何,都会执行的回调函数。
promise .then(result => {...}) .catch(error => {...}) .finally(() => {...})
将多个Promise实例,包装成一个新的Promise实例。 当实例列表中所有的状态都是resolved时,新实例的状态才会变成resolved,并将实例列表的返回值组成一个数组,传递给新实例的回调函数。 当实例列表中有一个的状态为rejected,新实例的状态就变成rejected,此时第一个被reject的实例的返回值,传递给新实例的回调函数。
const promises = [1, 2, 3].map(id => { return getJSON('/post/' + id + '.json'); }) Promise.all(promises).then(posts => { // ... }).catch(err => { // ... })
将多个Promise实例,包装成一个新的Promise实例。 当实例列表中一个实例率先改变状态,新实例的状态跟着改变。
将现有对象转为Promise对象。
const jsPromise = Promise.resolve($.ajax('/posts.json'));
返回一个新的Promise实例,该实例的状态为rejected。
var result1 = loadImg('url1'); var result2 = loadImg('url2'); result1.then(function() { console.log('第一张图片加载完成'); // 将result2返回出去,作为后续链式调用的主体 return result2; }).then(function() { console.log('第二张图片加载完成'); })
异步的同步写法
// 将函数定义为async函数 const load = async function() { // 执行loadImg异步函数,loadImg函数必须返回Promise实例 const result1 = await loadImg('url1'); console.log(result1); const result2 = await loadImg('url2'); console.log(result2); } load()
jQuery 1.5.0版本开始引入的一个新功能——deferred对象。deferred对象的含义就是"延迟"到未来某个点再执行。
deferred对象就是jQuery的回调函数解决方案
var waitHandler = function() { // 生成一个Deferred对象 var dtd = $.Deferred(); var wait = function(dtd) { var task = function() { console.log('Finshed'); if (success) { // 执行操作成功的回调 dtd.resolve(); } else { // 执行操作失败的回调 dtd.reject(); } } // 等待异步队列,然后进入task栈 setTimeout(task, 1000); // 最后将dtd返回出去,供链式调用 return dtd.promise(); // 返回promise对象,是为了防止链式调用时出现.reject()方法。 } // 进入wait栈 return wait(dtd); } var result = waitHandler(); // then写法 result.then(function() { // dtd.resolve()的回调函数 }, function() { // dtd.reject()的回调函数 }); // done+fail写法 result .done(function() { /* dtd.resolve()的回调函数 */ }) .fail(function() { /* dtd.reject()的回调 */ })
参考:ES6 - Promise
Promise里面保存着未来才会结束的事件(通常是一个异步操作)的结果。 Promise是一个对象,从它可以获取异步操作的消息。 Promise是一个构造函数,用来生成Promise实例。 Promise新建之后就会立即执行。
用Promise实现Ajax
Promise.prototype.then()
为Promise实例添加状态改变时的回调函数。
第一个参数是resolved状态的回调函数;第二个参数是rejected状态的回调函数。
then方法返回的是一个新的Promise实例,因此可以采用链式写法。
Promise.prototype.catch()
用于指定发生错误时的回调函数。
Promise.prototype.finally()
指定不管Promise对象最后状态如何,都会执行的回调函数。
Promise.prototype.all()
将多个Promise实例,包装成一个新的Promise实例。 当实例列表中所有的状态都是resolved时,新实例的状态才会变成resolved,并将实例列表的返回值组成一个数组,传递给新实例的回调函数。 当实例列表中有一个的状态为rejected,新实例的状态就变成rejected,此时第一个被reject的实例的返回值,传递给新实例的回调函数。
Promise.prototype.race()
将多个Promise实例,包装成一个新的Promise实例。 当实例列表中一个实例率先改变状态,新实例的状态跟着改变。
Promise.resolve()
将现有对象转为Promise对象。
Promise.reject()
返回一个新的Promise实例,该实例的状态为rejected。
应用:多个Promise串联
扩展:ES7 Async/Await
异步的同步写法
Promise 前传 - jQuery.Deferred
jQuery 1.5.0版本开始引入的一个新功能——deferred对象。deferred对象的含义就是"延迟"到未来某个点再执行。
deferred对象就是jQuery的回调函数解决方案
参考:ES6 - Promise