Q承诺什么时候被执行?

时间:2016-10-11 21:38:45

标签: javascript node.js q

我有一个(看似基本的)问题理解承诺。首先是代码:

'use strict';

var Q = require("q");

var mockPromise = function (statement) {
    var deferred = Q.defer();

    console.log("I'm running before I'm queued ...");

    setTimeout(function () {
        deferred.resolve(statement);
    }, 5000);

    return deferred.promise;
};

var promises = [
    mockPromise("1st statement"),
    mockPromise("2nd statement"),
    mockPromise("3rd statement")
];

Q.all(promises)
.then(function (results) {
    console.log(results);
});

每个promise函数在将其添加到promise数组时都会被调用,而不是像我想的那样调用Q.all时。

我没有到这里来的是什么?

如何在不立即调用所述承诺的情况下对一组承诺进行排队?

4 个答案:

答案 0 :(得分:2)

似乎令人困惑的是,您理解为惰性评估设计的promise API,但实际情况并非如此。

Promise是处理长时间运行请求的一种方式,它们旨在立即启动,以最大限度地减少等待时间,并利用链接和连接来阐明如何处理这些长时间运行请求的结果。

您可能会尝试使用api Q-Lazy,它允许您延迟调用promises,直到订阅为止。

答案 1 :(得分:2)

  1. Promise是对象。他们没有被执行#39;他们已经解决了#39;或者'拒绝'。创建数组时,您将执行mockPromise()函数三次。此功能立即在代码的该点执行。

  2. mockPromise()函数创建一个deferred并返回相关的promise。它还设置了一个计时器来解决将来返回的承诺。

  3. Q.all()等待3个承诺得到解决'。 (从技术上讲,它会返回一个新的承诺,将在解决前3个承诺时解决)

  4. 如果要一个接一个地执行三个异步函数,我建议使用优秀的async.js库。它提供了许多异步流控制原语。在您的情况下,您可能会对serieswaterfall方法感兴趣。

答案 2 :(得分:0)

您通常会推迟异步功能,而不仅仅是一个值。例如:

'use strict';

var Q = require("q");

var mockPromise = function (statement) {
    var deferred = Q.defer();

    console.log("I'm running before I'm queued ...");

    setTimeout(function () {
        deferred.resolve(statement());
    }, 5000);

    return deferred.promise;
};

var promises = [
    mockPromise(function() { 
        console.log("running1"); 
        return "1st statement";
    }),
    mockPromise(function() { 
        console.log("running2"); 
        return "2nd statement";
    }),
    mockPromise(function() { 
        console.log("running3"); 
        return "3rd statement";
    }),
];

Q.all(promises)
.then(function (results) {
    console.log(results);
});

请注意,延迟功能将运行,无论是否曾在承诺上调用.then

答案 3 :(得分:0)

让我用标准承诺展示一个样本。它们与Q承诺的工作方式几乎相同:

df %>% group_by(weekday, day, month, year, hour, period.h) %>% 
       summarise_all(funs(na.omit(.)[1]))