javascript - es6中的promise.all使用问题
阿神
阿神 2017-04-11 11:36:15
[JavaScript讨论组]

promise.all接收的promise数组是按顺序执行的还是一起执行的,也就是说返回的结果顺序是固定的吗。

edit1:
根据大家的回答,应该是同步执行的,但是这样就有效率问题了,如果想改成异步执行怎么办呢。

edit2:弄糊涂了,有些人认为结果是按顺序返回,有些人认为结果顺序不确定。

var a = new Promise(function  (resolve,reject) {
    setTimeout(function  () {
        resolve('aaa');
    },3000);
});

var b = new Promise(function  (resolve,reject) {
    setTimeout(function  () {
        resolve('bbb');
    },1000);
});

var p = Promise.all([a,b]);
p.then(function(val) {
    console.log(val);
});//结果:['aaa','bbb']

我写了个测试,可以看到a的时间虽然比较长,但a的结果确实排在了b的前面。
返回结果的确是按顺序排列的。但是,

var a = new Promise(function  (resolve,reject) {
    setTimeout(function  () {
        resolve('aaa');
    },3000);
});

var b = new Promise(function  (resolve,reject) {
    setTimeout(function  () {
        resolve('bbb');
    },3000);//改成3秒
});

var p = Promise.all([a,b]);
p.then(function(val) {
    console.log(val);
});//结果:['aaa','bbb']

将b的时间也改成3秒后,发现整体运行时间并没有改变。

所以我认为,promise应该是并发执行的,这样的话结果返回的顺序应该也是乱的,但promise.all内部不晓得做了啥处理,让返回结果的排序又正常了。

不晓得我的理解对不对。

阿神
阿神

闭关修行中......

全部回复(7)
ringa_lee

给你这段代码可以来理解。

const getRandom = () => +(Math.random()*1000).toFixed(0);

const asyncTask = taskID => new Promise(resolve => {
    let timeout = getRandom();
    console.log(`taskID=${taskID} start.`);
    setTimeout(function() {
        console.log(`taskID=${taskID} finished in time=${timeout}.`);
        resolve(taskID)
    }, timeout);
});

Promise.all([asyncTask(1),asyncTask(2),asyncTask(3)])
.then(resultList => {
    console.log('results:',resultList);
});

运行三次,结果如下

由此可见,Promise.all里的任务列表[asyncTask(1),asyncTask(2),asyncTask(3)],是按顺序发起的,由于它们都是异步的,互相之间并不阻塞,每个任务完成时机是不确定的。尽管如此,所有任务结束之后,它们的结果仍然是按顺序地映射到resultList里,这样就能和Promise.all里的任务列表[asyncTask(1),asyncTask(2),asyncTask(3)]一一对应起来。

黄舟

Promise.all(promiseArray)
promiseArray里比方有10个请求,是同步发的(按照顺序全部请求出去,不过也会根据浏览器最大http请求的限制分批发),不过谁的结果先回来谁也不晓得的。

巴扎黑

都是异步的,天知道哪个先返回……

怪我咯

是的!

MDN 的 syntax 說明 Promise.all(iterable); 裡面是 Iterator 所以會照順序。

巴扎黑

Promise.all方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例。
结果顺序是固定的,与传入的Promise实例一致。

怪我咯

Promise.all() 这个 API 的意思是同时请求,等待所有结果返回。所以所用的时间肯定是慢的那个Promise执行的时间 (3s);

如果你想要是,谁最先返回就用谁的结果,那么请用Promise.race()

伊谢尔伦

谢邀!
promise.all内部的确是顺序执行的,如下

var a = new Promise(function  (resolve,reject) {
    console.log(1);
    setTimeout(function  () {
        console.log(11);
        resolve('aaa');
    },1000);
});

var b = new Promise(function  (resolve,reject) {
    console.log(2);
    setTimeout(function  () {
        console.log(22);       
         resolve('bbb');
    },300);
});

var p = Promise.all([a,b]);
p.then(function(val) {
    console.log(val);
});

});
// 1
// 2
// 22
// 11
// ["aaa", "bbb"]

你可以去看看源码,在内部函数都执行完了以后才会去执行回调, https://www.promisejs.org/api/

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号