节点promises.all()不按预期方式工作

我试图在使用promise.all()循环后同步运行一个函数列表,但我的代码不能按预期方式工作。

有人知道我做错了什么吗?

我的代码是:

 var Promise = require('promise'); var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.all(promises) .then(function (data) { console.log("done"); }); function foo(i) { return new Promise(function (resolve, reject) { console.log('---> foo i ' + i); resolve('done foo ' + i); }); } 

但输出是

 push promise 0 ---> foo i 0 push promise 1 ---> foo i 1 push promise 2 ---> foo i 2 done 

我期待的地方

 push promise 0 push promise 1 push promise 2 ---> foo i 0 ---> foo i 1 ---> foo i 2 done 

先谢谢你。

这里发生的是,当你调用promise构造函数时,传递给它的函数在施工调用期间被调用。 如果您在承诺(这是预期的用例)内有asynchronous调用,那么它会创build您期望的行为。

这里是我的示例代码,使用setTimeout作为asynchronous调用,并注意如何在asynchronouscallback中进行resolve调用。

 var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.all(promises) .then(function (data) { console.log("done"); }); function foo(i) { return new Promise(function (resolve, reject) { // The async call is made inside the Promise setTimeout(()=> { console.log('---> foo i ' + i); // And the resolve call is made inside the callback function resolve('done foo ' + i); }); }); } 

如果你运行这个,你应该得到你想要的输出(用chrometesting):

 push promise 0 push promise 1 push promise 2 ---> foo i 0 ---> foo i 1 ---> foo i 2 done 

附录:这只适用于( foo i 0, ... 1 ... 2 ),因为这些请求都是一个接一个地立即完成的。 如果是ajax调用,foo语句将按照完成顺序打印。 所以如果请求2在0或1之前完成,你会先看到foo i 2 。 但是只有当所有的请求都被解决后才能看到。

我试图在使用promise.all()循环后同步运行一个函数列表,但我的代码不能按预期方式工作。

我想你想同步运行一个function列表。 如果是这样,我推荐使用Bluebird Promise.each()

 var Promise = require('bluebird'); var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.each(promises, function(result) { console.log(result); }); function foo(i) { return new Promise(function (resolve, reject) { resolve('done foo ' + i); }); } 

结果:

 push promise 0 push promise 1 push promise 2 done foo 0 done foo 1 done foo 2 

你的console.log('---> foo i ' + i); 因为它在resolve方法之外,所以在创buildpromise时执行了这一行,而是在您提供给Promise构造函数的executor函数中执行。

这应该给你你的预期输出

 var Promise = require('promise'); var promises = []; for (var i = 0; i < 3; i++) { console.log('push promise ' + i); promises.push(foo(i)); } Promise.all(promises) .then(function (data) { for (var i = 0; i < data.length; i++) { console.log(data[i]); } console.log("done"); }); function foo(i) { return new Promise(function (resolve, reject) { resolve('--> foo i ' + i); }); }