const getRandom = () => +(Math.random()*1000).toFixed(0); function test(taskID) { new Promise( (resolve) => { // 随机获取一次0~1000的随机数 let timeout = getRandom(); // 打印出传递进来的ID号 console.log(`taskID=${taskID} start.`); setTimeout(function() { console.log(`taskID=${taskID} finished in time=${timeout}.`); resolve(taskID) }, timeout); } ) } Promise.all([test(1),test(2),test(3)]) .then(resultList => { console.log('results:',resultList); });
我们先来看一下结果是怎样的?
第一次:
taskID=1 start. taskID=2 start. taskID=3 start. results: Array(3) [undefined, undefined, undefined] taskID=1 finished in time=460. taskID=2 finished in time=704. taskID=3 finished in time=883.
第二次:
taskID=1 start. taskID=2 start. taskID=3 start. results: Array(3) [undefined, undefined, undefined] taskID=2 finished in time=17. taskID=3 finished in time=212. taskID=1 finished in time=612.
第三次:
taskID=1 start. taskID=2 start. taskID=3 start. results: Array(3) [undefined, undefined, undefined] taskID=3 finished in time=130. taskID=1 finished in time=256. taskID=2 finished in time=593.
实验还是要至少做上3次以上才有说服力。
通过输出结果我们能够看出返回的数组内的数据都为undefined。我们就要找出这个原因,那就是找到了为什么要使用箭头函数。
首先我通过调试来查找
如图:
程序首先打印出了
taskID=1 start.
taskID=2 start.
taskID=3 start.
说明一定是先执行了
console.log(`taskID=${taskID} start.`);
所以我们在这段打上断点进行一步一步调试,如下:
根据上图我们可以看出console.log(taskID=${taskID} start.)每次都会被执行,setTimeout也会被执行,但是3次之后,就会直接开始执行.then(),所以我们找到了原因,Promise.all()这时并没有等待返回完整的数据就执行了.then(),没有等到resolve就开始执行了。
说明这里面出现了异常,而这个异常就是由于Promise.all()内的参数,存在函数,造成this混淆,所以我们要使用对象,更准确的说法就是实例。
注意:
以这段代码为例:
var p1 = Promise.resolve(1), p2 = Promise.resolve(2), p3 = Promise.resolve(3); Promise.all([p1, p2, p3]).then(function (results) { console.log(results); // [1, 2, 3] });
在上面的方法中,promise数组中所有的promise实例都变为resolve的时候,该方法才会返回,并将所有结果传递results数组中。promise数组中任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象。reject使用示例如下:
var p1 = Promise.resolve(1), p2 = Promise.reject(2), p3 = Promise.resolve(3); Promise.all([p1, p2, p3]).then(function (results) { //then方法不会被执行 console.log(results); }).catch(function (e){ //catch方法将会被执行,输出结果为:2 console.log(2); });