一直恐惧读源码,哪怕是一个简单的库也是读百来行遇到难点就放弃了。对于新的东西也仅仅是知道它拿来干什么,社区资源在哪里,要用时就突击文档资源使用即可。未有过深入之心,亦或者有过深入之心两三天就废掉。
这两日安静下来思考,觉得自己毛病不少,却还是不甘于平庸。那么只能选择面对自己做出改变,越是恐惧,越是应该面对。下一篇就来个 es6-promise 代码理解好了。加油吧少年!
Promise.reject() 静态方法, 这个方法我在才开始用的时候老迷惑了,不知道什么时候应该使用。直到我理解了 then 方法过后,就不迷惑了,接上一篇。看下图代码:
- varaPromise =newPromise(function() {
- resolve(1)
- });
- vartestPromise = aPromise.then(function onFulfilled() {
- //...一系列操作过后得到要接受的value 值
- return value
- })
- //或者
- varaPromise =newPromise(function() {
- reject(1)
- });
- vartestPromise = aPromise.then(null, onRejected() {
- //...一系列操作过后得到要接受的reason 值
- return reason
- })
Promise.prototype.then 执行它会返回一个新的 promise 对象, 而这个新的 promise 对象的状态值规则如下:
①var aPromise = new Promise(function(){resolve(1)}); var testPromise = aPromise.then()//then 没有接收回调函数,新创建的 testPromise 对象的 [[PromiseStatus]] 和[[PromiseValue]]与之前的 aPromise 的一样。
②then 方法接收的回调函数执行 return 值只为普通对象或者原始类型,即将普通对象或者原始类型值赋给新创建的 promise 对象 [[PromiseValue]], 新创建的 promise 对象的[[PromiseStatus]] 就等于调用 then 的那个 promise 对象的[[PromiseStatus]]。
③then 方法接收的回调函数执行 return 值为 promise 对象,即将 promise 对象的 [[PromiseValue]] 和[[PromiseStatus]]赋值给新创建的 promise 对象对应属性值。
④then 方法接收的回调函数执行 return 值为 thenable 对象,即执行对象的 then 方法,根据 then 方法内部执行 resolve 或 reject 确定 [[PromiseValue]] 和[[PromiseStatus]],赋值给新创建的 promise 对象对应属性值。
then 函数最后调用了 onRejected 或者 onFulfilled 返回的 promise 对象需要把 rejected 状态传递下去(传递给后续进行处理)此时需要使用 Promise.reject。(举个例子看下图代码)
- // Request.get()是一个发起请求,当有数据返回或请求出错时生成一个promise对象
- // res为后台成功返回的数据,msg为失败或错误返回的数据
- axios.get(url).then((res) = >{
- if (res.code == 0) {
- //当code的值为0 时判定这个是成功的需要处理的数据
- return res;
- } else {
- //当code的值不为0时,就需要返回一个rejected的promise对象供后续处理
- return Promise.reject(res));
- }
- },
- (msg) = >{
- //通常是请求出错需要返回一个rejected的promise对象,供后续处理
- return Promise.reject(msg);
- });
如图中代码,当需要把错误抛出给后续做处理的时候,通常会 return Promise.reject("原因") 给后续的代码来处理 (此时的错误可以是我们与后台约定的错误码,而不一定是代码上的错误)。
Promise.reject() 执行后返回的结果又是什么了?
①reject, 中不接收值时返回一个 rejected 状态的 promise 对象 [[PromiseValue]] 值为 undefined
②reject 中接收普通值和对象,会作为返回的 rejected 状态的 promise 对象的 [[PromiseValue]] 值。
- //创建一个 thenable 对象
- var thenable = {
- then(resolve, reject) {
- reject('错误原因');
- }
- };
- //将 thenable 作为参数使用
- var testC = Promise.reject(thenable);
- // 此处判定 e 与 thenable
- testC.
- catch(e = >{
- console.log("我居然是接受进来的thenable对象", e === thenable)
- })
③reject 中接收 thenable 对象,直接作为返回的 rejected 状态的 promise 对象的 [[PromiseValue]] 值。(此处可以在控制台输出 testC,查看他的结构)
④reject 中接收 thenable 对象,直接作为返回的 rejected 状态的 promise 对象的 [[PromiseValue]] 值。(看上图)
Promise.reject()方法接受的参数,会原封不动地作为 reject 的理由,成为新 promise 对象的 [[PromiseValue]] 值(厉害了一点转化都不会做,废话如果 rejected 状态可以变化,还要 Promise.reject()有何有)。
总结:Promise.reject() 返回一个使用接收到的值进行 reject 的新的 promise 对象。(promise 对象是 rejected 的哟)
Promise.resolve 一个作用就是将 thenable 对象转换为 promise 对象。同理 Promise.resolve 方法是创建 promise 对象的快捷方式。
thenable 指的是一个具有 .then 方法的对象。目前我们最常见的 thenable 对象就是 jQuery.ajax()
1. 当接受一个普通对象或值的时候
Promise.resolve 返回的是一个将该对象作为值的新 promise 对象。
2. 接受一个 thenable 对象的时候
执行 thenable 的 then 方法,根据 then 方法内部执行 resolve 或 reject 确定 [[PromiseValue]] 和[[PromiseStatus]],然后将值赋给新的 promise 对象。
3. 接收到 promise 对象参数的时候
返回的还是接收到的 promise 对象
突然想什么场景下适合使用 Promise.all,Promise.all 简单描述它接收一个 promise 对象的数组作为参数,当这个数组里的所有 promise 对象全部变为 fulfilled 或有对象变为 rejected 状态的时候,它就会去调用
方法。
- .then
1. 当接受到 promise 对象数组都 fulfilled
Promise.all([testA,testB,testC]).then() , 接受的数组中 testA,testB,testC 会同时执行,promise 对象只会状态迁移一次,所以 testA,testB,testC,有 fulfilled 状态的就等待其他的 promise 对象状态迁移完成,然后在返回一个新的 promise 对象,then 方法接受的参数是 Promise.all 接受到的 promise 对象 resolve 的值组成的数组,所以 then 接收的数组是类似 [testAresolveValue, testBresolveValue, testCresolveValue]),数组顺序跟接收的 promise 对象数组顺序一致。
2. 当接受到 promise 对象数组有 rejected
Promise.all([testA,testB,testCReject]).then() , 它的执行跟前面场景一致,不同在数组中有 promise 对象 rejected 状态就会执行. then 方法。其它数组中还没状态迁移的 promise 对象还会执行,只是和后续的链式操作没有什么关系了。
总结:Promise.all 接受的数组,数组中的 promise 对象都 fulfilled,Promise.all 返回的新 promise 才会是 fulfilled 状态的,只要数组中有一个 promise 对象是 rejected 状态,Promise.all 返回的新 promise 会是 rejected 状态的。但是数组中的 promise 对象都会状态迁移到稳定(也就是说数组中有 promise 对象 rejected 状态就会执行. then 方法。但其它数组中还没状态迁移的 promise 对象还会执行的,比如上图中 "执行了 C" 是在 "B:32" 之后输出的);Promise.all 适用的场景是多个异步条件需要同时满足才执行后续操作的情况。
Promise.race() 跟 Promise.all() 使用方法一致,接收一个 promise 对象数组为参数,但不同的是 Promise.race() 接收的 promise 对象数组中有一个 promise 对象进入 FulFilled 或者 Rejected 状态的话,就会执行. then 继续进行后面的处理 (就像比赛一样谁先到达,谁就接着后续操作)。
第一个 promise 对象变为确定(FulFilled)状态后,数组中其它的 promise 对象还是会继续运行的,所有手续输出了 "执行了:B","执行了:C"。
总结:Promise.race() 接收的数组中的 promise 对象存在竞争关系,比如同时向两个不同接口拿相同数据,哪个接口先返回数据,就先使用该数据做后续操作。 也可以做超时限制如下图(附带码)。
View Code
- function timeOut(time) {
- return new Promise((resolve, reject) = >{
- setTimeout(function() {
- reject('timeOut');
- },
- time)
- })
- }
- function promiseURL() {
- return new Promise((resolve, reject) = >{
- setTimeout(function() {
- reject('get Date from promiseURL');
- },
- 1000)
- })
- }
- Promise.race([promiseURL(), timeOut(2000)]).then(function(values) {
- console.log(values); // get Date from promiseURL
- },
- function(res) {
- console.log(res); // timeOut
- })
终于把这篇结尾了,还好这个周时间充足,准备把前面两篇修改整理一下,顺带做做 es6-promise 源代码理解笔记。
~~~~~~~~~ 总结好像简单了点哟~~~~~~~~~~~~~~~ 哈哈哈哈哈~~~~~~~~~~~ 打完收工~~~~~~~~~
睡觉。
来源: http://www.cnblogs.com/luoxiaoer/p/7053781.html