0

在阅读了 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行,其中任何给定的行都可以通过从该行检索到的值来减少计数。通过循环的次数取决于数据。

4

2 回答 2

0

计数将异步递减,因此您必须在 successsfullthen回调中打印它:

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
于 2013-09-03T20:57:43.817 回答
0

如果不引入线程或纤程,就不可能使异步操作看起来像同步操作。因此,您需要将您的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();
于 2013-09-04T19:43:30.697 回答