【问题标题】:Control asynchronous execution flow in node.js/meteor在 node.js/meteor 中控制异步执行流程
【发布时间】:2014-05-15 19:05:57
【问题描述】:

我正在使用带有来自大气的“http-methods”包和来自 npm 的“node-sqlite3”包的陨石应用程序。考虑流动的代码。

var results = null;
HTTP.methods({
    'list': function(data) {
      var sqlite3 = Npm.require('sqlite3').verbose();
      var db = new sqlite3.Database(':memory:');

      db.serialize(function() {
        db.run("CREATE TABLE lorem (info TEXT)");

        var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
        for (var i = 0; i < 10; i++) {
            stmt.run("Ipsum " + i);
        }
        stmt.finalize();

        db.all("SELECT rowid AS id, info FROM lorem", function(err, rows) {
            console.log(rows);
            results = rows;
        });
      });

      console.log("Closing DB");
      db.close();

      console.log("Sending back response");
      console.log(results);

      return results;
    }
  });

这里使用域/列表调用上述函数。我想返回 resultSet 作为对请求的响应。但取而代之的是返回“null”。控制台的输出如下所示。

I20131229-23:50:20.092(1)? Closing DB
I20131229-23:50:20.113(1)? Sending back response
I20131229-23:50:20.117(1)? null
I20131229-23:50:20.172(1)? [ { id: 1, info: 'Ipsum 0' },
I20131229-23:50:20.181(1)?   { id: 2, info: 'Ipsum 1' },
I20131229-23:50:20.182(1)?   { id: 3, info: 'Ipsum 2' },
I20131229-23:50:20.183(1)?   { id: 4, info: 'Ipsum 3' },
I20131229-23:50:20.199(1)?   { id: 5, info: 'Ipsum 4' },
I20131229-23:50:20.199(1)?   { id: 6, info: 'Ipsum 5' },
I20131229-23:50:20.199(1)?   { id: 7, info: 'Ipsum 6' },
I20131229-23:50:20.202(1)?   { id: 8, info: 'Ipsum 7' },
I20131229-23:50:20.202(1)?   { id: 9, info: 'Ipsum 8' },
I20131229-23:50:20.203(1)?   { id: 10, info: 'Ipsum 9' } ]

请针对该问题提出适当的解决方案。

注意:给出的代码是实际代码的同义词。如果您想了解更多详情,请告诉我。

【问题讨论】:

    标签: node.js sqlite meteor


    【解决方案1】:

    编辑:您在 db 回调之前输出“结果”。您还可以在进行查询后立即关闭数据库连接。我可以猜测 db 模块在关闭之前完成了查询,因为它最终会输出返回的行。

    您需要在回调中关闭并返回。

    db.all("SELECT rowid AS id, info FROM lorem", function(err, rows) {
        console.log(rows);
        results = rows;
    
        db.close();
        callback(results);
    });
    

    编辑:

    这是一个更好的例子,使用回调而不是返回:

    var results = null;
    HTTP.methods({
    'list': function(data, callback) {
      var sqlite3 = Npm.require('sqlite3').verbose();
      var db = new sqlite3.Database(':memory:');
    
      db.serialize(function() {
        db.run("CREATE TABLE lorem (info TEXT)");
    
        var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
        for (var i = 0; i < 10; i++) {
            stmt.run("Ipsum " + i);
        }
        stmt.finalize();
    
        db.all("SELECT rowid AS id, info FROM lorem", function(err, rows) {
            console.log(rows);
            results = rows;
    
            db.close();            
    
            // this returns the data in a callback function
            callback(results);
        });
      });
    
      // this will return 'results' before the query returns any results
      // return results;
    }
    });
    

    【讨论】:

    • 您的回答无效。 'db.all' 调用启动新的并行/异步执行。在一个执行流程中获取查询结果时,将空响应发送回客户端。 (“db.all”回调中的所有内容都在一个线程中执行,其余代码在主线程中执行)。我需要一些机制来停止主线程的执行,直到另一个线程完成,或者需要一些机制来使“db.all”在同一个线程而不是新线程中执行。
    • 您的解决方案没有解决问题。响应仍然返回为 null。
    【解决方案2】:

    您可以通过放置javascript的延迟方法来解决此问题,该方法会在指定的时间内停止执行。您可以停止执行几秒钟,您的问题将得到解决。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 2020-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多