Q承诺&同步I/O

Q promise & synchronous I/O

本文关键字:同步 承诺 amp      更新时间:2023-09-26

在阅读了Q文档后,我认为以下内容将等待SELECT,从而提供同步I/O功能。假设db是一个开放的SQLite数据库。

   count = 500;
   Q.invoke(db, 'get', "SELECT * FROM blah blah ...").done(
      function () { --count; },
      function () { // error code}
   );
   console.log(count);

测试表明这不是真的。如何通过promise方法同步SELECT及其结果,使控制台输出为499?

我真的想把它封装在一个while循环中,该循环处理X行数,其中任何给定的行都可以将计数减少从该行检索到的值。循环的次数取决于数据。

如果不引入线程或光纤,就不可能使异步操作看起来像同步操作。因此,您需要将console.log放入处理程序中,该处理程序会在操作完成时通知您。

var count = 500;
Q.invoke(db, 'get', "SELECT * FROM blah blah ...")
.then(function (results) {
    for (var i = 0; i < results.length; i++) {
        var result = results[i];
        --count;
    }
})
.done();

某些数据库API将允许您流式传输结果。您需要在文档中查找。理想情况下,它看起来像:

var count = 500;
Q(db)
.invoke("getStream", "SELECT * FROM blah blah blah")
.invoke("forEach", function (result) {
    --count;
})
.then(function () {
    assert.equals(count, 0);
})
.done();

Count将异步递减,因此您必须在成功的then回调中打印它:

count = 500;
Q.invoke(db, 'get', "SELECT * FROM blah blah ...").then(
  function () { --count; console.log(count); },
  function () { // error code}
);

您不能真正将其放入循环中,因为promise不会以任何方式使您的代码同步。我认为你真正想要的是承诺/生成器组合:

Q.async(function* () {
  var count = 0;
  // Notice the regular loop here
  while (count > 0) {
    count -= yield Q.invoke(db, 'get', 'SELECT * FROM blah blah ...');
    console.log(count);
  }
});

注意这里的两个新构造:yield关键字和function*声明。ECMAScript 6正在进行这些工作。

如果你正在使用Node.js,你今天就可以试用一下。只需运行带有和谐标志的节点:

$ node --harmony --harmony-generators script.js