node promises.all()没有按预期工作

时间:2017-11-17 04:48:38

标签: node.js promise

我尝试在使用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

提前谢谢。

3 个答案:

答案 0 :(得分:2)

这里发生的是当你调用promise构造函数时,在构造调用期间调用传递给它的函数。 如果异步调用在promise中(这是预期的用例),那么它将创建您期望的行为。

以下是我的示例代码,使用setTimeout作为异步调用,并注意如何在异步回调中进行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);
        });
    });
}

如果你运行它,你应该得到你想要的输出(用chrome测试):

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。但done只有在所有请求都得到解决后才会显示。

答案 1 :(得分:0)

  

我试图在使用promise.all()循环后同步运行一系列函数,但我的代码没有按预期工作。

我想你想同步运行一系列功能。如果是这样,我建议使用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

答案 2 :(得分:-1)

您的#suggestion.rb scope :sorted_by, lambda { |sort_option| # extract the sort direction from the param value.\ direction = (sort_option =~ /desc$/) ? 'desc' : 'asc' case sort_option.to_s when /^created_at_/ order("suggestions.created_at #{ direction }") else raise(ArgumentError, "Invalid sort option: #{ sort_option.inspect }") end } filterrific( default_filter_params: { sorted_by: "created_at_asc" }, #I changed this to ascending order, but it always sorts in descending order available_filters: [ :sorted_by ] ) #suggestions_controller.rb def index @filterrific = initialize_filterrific( Suggestion, params[:filterrific] ) or return @suggestions = @filterrific.find.page(params[:page]) respond_to do |format| format.html format.js end ... #other code 行正在执行承诺,因为它在console.log('---> foo i ' + i);方法之外,而是在您提供给resolve构造函数的执行函数内。

这可以为您提供预期的输出

Promise