Q promises 什么时候执行?

When do Q promises get executed?

我在理解 promises 时遇到了(看似基本的)问题。先上代码:

'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。

我没有得到什么?

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

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

'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

似乎混淆是因为您理解为惰性求值而设计的承诺 API,但事实并非如此。

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

您可以尝试使用 api Q-Lazy,它允许您延迟调用承诺,直到它们被订阅。

让我展示一个使用标准承诺的示例。它们的工作原理与 Q 承诺的几乎相同:

function mockPromise(value) {
  return new Promise(resolve => {
    console.log("I'm not running before I'm queued ...");
    setTimeout(() => {
      resolve(value);
    }, 1000);
  });
}

mockPromise("1st promise").then(x => {
  console.log(x);
  return mockPromise("2nd promise");
}).then(x => {
  console.log(x);
  return mockPromise("3nd promise");
}).then(x => {
  console.log(x);
});

  1. 承诺是对象。他们不是 'executed'。它们是 'resolved' 或 'rejected'。创建数组时,将执行三次 mockPromise() 函数。该函数会在代码的那一点立即执行。

  2. mockPromise() 函数创建延迟和 returns 关联的承诺。它还设置了一个计时器来解决将来返回的承诺。

  3. Q.all() 只是等待 3 个承诺成为 'resolved'。 (从技术上讲,它是 returns 一个新的承诺,它将在前 3 个承诺得到解决时得到解决)

如果你想一个接一个地执行三个异步函数,我会推荐使用优秀的async.js library. It provides many async flow control primitives. In your case you may be interested in series or waterfall方法。