标签:很多 highlight 异步 iter 总结 class 等价 定义 taobao
promise最早是在commonjs社区提出来的,当时提出了很多规范。比较接受的是promise/A规范。后来人们在这个基础上。提出了promise/A+规范,也就是实际上的业内推行的规范。es6也是采用的这种规范。
promise/A规范在这里
不过规范这种东西看着比较晦涩。下面具体说说promise的用法。
什么是promise呢,说白了就是一个承诺,我承诺你叫我做的事情我将来会去做,不过要等我能去做的时候。
一个promise对象有三种状态,预备状态(pending),成功态(fulfilled),失败态(rejected)。
我们看下promise对象的构造函数:
1 2 3 4 5 6 7 8 9 10 11 | var promise = new Promise(function(resolve, reject) { //reject(new Error('promise出错啦。。')) //} //某个异步操作,比如ajax请求 setTimeout(function(){ resolve('异步请求结束了。。变成完成态') },1000) }); |
promise对象初始状态一般是预备状态,并且promise对象的状态转换只能是预备状态到成功态或者预备状态到失败态。
我们可以使用promise对象的then方法往这个对象里面添加回调函数。调用方式为:
1 | promise.then(onFulfilled, onRejected) |
then接受一个成功回调,还有失败回调。都是可选参数。
当promise对象是预备状态这些函数不会立即执行。而是等待。
当promise对象变成了成功态会调用onFulfilled,参数为resolve传递的值。
变成失败态则会调用onRejected,参数为reject传递的值。
因为then返回一个promise对象。所以支持链式调用:
1 | promise.then(onFulfilled, onRejected).then(onFulfilled, onRejected) |
then负责往promise对象里添加函数,随便添加多少。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //onRejected可以为null也可以省略 promise.then(function(prevValue){ console.log('resolve的值:'+prevValue) return "我是传递给第二个回调的参数" },null).then(function(value){ console.log('报告:'+ value) console.log('我是最后一个') }) /* *结果 resolve的值:异步请求结束了。。变成完成态 报告:我是传递给第二个回调的参数 我是最后一个 */ |
可以看到一直等到前面的异步操作结束了,后面的才会执行。
此外如果onFulfilled返回一个新的promise对象,那么之后的then添加的操作函数会被托管给新的promise对象。然后之后的操作函数执不执行就由新的promise对象说了算了。
比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | promise.then(function(prevValue){ console.log('resolve的值:'+prevValue) var newPromise = new Promise(function(resolve,reject){ setTimeout(function(){ resolve('2秒后,新的promise变成完成态') },2000) }) //返回新的promise console.log('返回一个promise,开始托管。') return newPromise },null).then(function(value){ console.log('报告:'+ value) console.log('我是最后一个') }) /* *结果 resolve的值:异步请求结束了。。变成完 大专栏 promise规范成态 返回一个promise,开始托管。 报告:2秒后,新的promise变成完成态 我是最后一个 */ |
用来捕获上一个then方法里面reject过来的错误,说白了就是一种特殊的then
1 2 3 4 5 6 7 8 9 | promise.catch(function(error) { console.log('发生错误!', error); }); //等价于 promise.then(null,function(error) { console.log('发生错误!', error); }); |
Promise.resolve
接受的参数如果是promise对象就直接返回。
如果是一个非promise,但具有then方法的对象就会尝试转换成一个成功状态的promise对象。
如果是个不具有then方法的值就传递给下一个onFulfilled函数,并且生成一个处于成功状态的promise对象。
Promise.reject
接受的参数如果是promise对象就直接返回。
如果是一个非promise,但具有then方法的对象就会尝试转换成一个失败状态的promise对象。
如果是个不具有then方法的值就传递给下一个onRejected函数。并且生成一个处于失败状态的promise对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var a = Promise.resolve(true) //same as var a = new Promise(function(resolve,reject){ //立即变成成功状态 resolve(true) }) var b = Promise.reject(true) //same as var b = new Promise(function(resolve,reject){ //立即变成失败状态 reject(true) }) //使用Promise.resolve转换不标准的jQuery的promise对象 var promise = Promise.resolve($.get('http://www.taobao.com')); |
Promise.all用来包装一系列的promise对象返回一个包装后的promise对象,比如我们称之为A。
1 2 3 4 | var a = new Promise(function(resolve,reject){}) var b = Promise.resolve(true) Promise.all([a,b]) |
Promise.race也是用来包装一系列的promise对象返回一个包装后的promise对象,比如我们称之为B。跟all不同的是,只要有一个对象变成了成功状态(fulfilled),B就会变成成功状态。
1 | Promise.race([a,b]) |
all是一种与的关系,而race是一种或的关系。
其实除了在构造函数里面使用resolve,reject去改变一个promise对象的状态外,我们还有另外一种方式。那就是defer。
例子:
1 2 3 4 5 6 7 8 9 10 | promise.then(function(val){ var d = Promise.defer() setTimeout(function(){ d.resolve('2秒后,新的promise变成完成态') //d.reject('err') },2000) //返回自己的promise对象 return d.promise }) |
Promise.defer()
生成一个defer对象。这个对象d具有一个promise对象属性。d.resolve会把管理的promise变成完成态,同理d.reject会将管理的promise变成失败态。
整个promise的用法就说完了。
其实A+规范中只定义了then函数的具体细节,而promise状态的改变都是前人的经验慢慢积累后总结出的一套使用方式
参考链接:
标签:很多 highlight 异步 iter 总结 class 等价 定义 taobao
原文地址:https://www.cnblogs.com/dajunjun/p/11711242.html