Q promise&同步I / O.

时间:2013-09-03 20:54:15

标签: javascript sqlite promise

在阅读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?

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

2 个答案:

答案 0 :(得分:0)

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

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

你不能把它放到循环中,因为promises不会以任何方式使你的代码同步。我认为你真正想要的是承诺/发电机组合:

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

答案 1 :(得分: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();