promise学习(3)
Promise.race
// `delay`毫秒后执行resolve function timerPromisefy(delay) { return new Promise(function (resolve) { setTimeout(function () { resolve(delay); }, delay); }); } // 任何一个promise变为resolve或reject 的话程序就停止运行 Promise.race([ timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128) ]).then(function (value) { console.log(value); // => 1 });
Promise.race 是当接受的参数数组中有一个promise对象进入fulfilled或者rejected状态的时候就停止运行。此时,由于只有一个promise的状态能够确定,所以then执行的是唯一那个确定状态的resolve函数,而不会执行其他的resolve,但是并不会阻止其他promise的执行。
关于promise.race的使用
我们知道promise.race如果参数promise数组中只要有一个promise状态改变就会执行后续的回调,那么如果参数数组中最先返回的是失败状态,那就直接走到了rejected,其实这违背了我们使用的初衷。不过参数中promise状态的改变是由开发者控制的,如果不想发生这样的情况,可以在promise定义的时候设置好错误处理,保证promise.race需要解析的一定是确定的状态。
在实际应用中,promise.race常用来设置超时操作,比如接口请求超时等。而且要注意不要给promise.race传入空数组,那么这个promise将不会被解析。
为什么使用then每次需要创建一个新的promise
如果没有创建新的promise,每次都是返回之前的promise,那么当最开始promise的状态发生改变之后,后续的promise状态其实已经固定不会再改变了。这就无法实现promise的功能,所以每次的promise对象都应该相互独立,互相不影响。
看似矛盾的问题
let promise1 = Promise.resolve() let promise2 = promise1.then(function foo(value) { return Promise.reject(3) })
执行结果:
看似矛盾,promise1明明执行了成功的回调,为什么最后promise2的状态是rejected。原因是在调用then的时候,创建了新的promise,此时与promise1已经没有关系了,返回的时候改变的是新创建的promise的状态,变为rejected。
不过看了下Promises/A+的标准,这边叙述貌似还有些需要再研究确认一下的地方。
标准中说,如果onFulfilled或者onRejected返回一个promise对象(thenable对象),那么promise2会接受x的状态。上述代码似乎执行结果与标准中的叙述有矛盾,这个问题还需要再思考下。
【思考】
这个其实并不是矛盾,promise2接受的是返回的promise的状态,与原来的没有关系。这边确实很容易混淆。
关于promise.then链式调用时参数value的传递
promise1.then(function func(value){ console.log('1-'+value) return value * 2 }).then(function func(value){ console.log('2-'+value); }).then(function func(value){ console.log('3-'+value) })
执行结果
可以看到,如果不使用没有return,那么上一个then的执行结果并不会传递到下一个then当中。
【思考】
有些问题如果觉得有疑惑或者弄不太清,那就一定要想着写个demo运行看下,不能靠直觉或者思维定势去想结果,毕竟~实践是检验真理的唯一标准~