使用node.js + Q deferred / promises模块从同步回调创建同步循环

时间:2013-02-17 01:02:44

标签: javascript node.js loops q

流行的JavaScript模块Q实现了延迟/承诺/期货概念。我认为它主要用于node.js,但它也支持浏览器使用。我正在使用node.js。

要进行顺序调用,您可以使用then()将一个承诺链接到下一个承诺,但是在一个循环中,它可能会比我发现难以像这个伪代码那样做违反直觉:

forever {
    l = getline();

    if (l === undefined) {
        break;
    } else {
        doStuff(l);
    }
}

Q文档包含一个看似非常相似的示例:

var funcs = [foo, bar, baz, qux];

var result = Q.resolve(initialVal);
funcs.forEach(function (f) {
    result = result.then(f);
});
return result;

但是,在尝试多种方式使这个例子适应我的问题时,我根本没有成功。

与示例代码不同,我不是迭代数组但希望循环直到满足结束条件。我总是称同一个功能。我的函数不会将先前的结果作为下一个调用的参数。每次调用都不带参数,但返回值决定是否继续循环。

这些看似微不足道的差异正在造成某种不可逾越的心理障碍。现在我可以看到为什么很多人都无法理解承诺。

2 个答案:

答案 0 :(得分:6)

要记住的关键是,如果您从then回调中返回承诺,那么它将取代现有的承诺。这个想法是,在循环体中执行你想要做的任何事情链的一次迭代之后,你要么返回一个值,它将解析promise,要么你返回一个新的promise,它将再次执行循环体。

function iterateUntil(endValue){
  // This line would eventually resolve the promise with something matching
  // the final ending condition.
  return Q.resolve('some value')
    .then(function(value){
      // If the promise was resolved with the loop end condition then you just
      // return the value or something, which will resolve the promise.
      if (value == endValue) return value;

      // Otherwise you call 'iterateUntil' again which will replace the current
      // promise with a new one that will do another iteration.
      else return iterateUntil(endValue);
    });
}

答案 1 :(得分:0)

这不是特定于Q:Synchronous for loop