【问题标题】:How should I implement asynchronous function in Javascript with node.js and Mongodb?我应该如何使用 node.js 和 Mongodb 在 Javascript 中实现异步函数?
【发布时间】:2017-10-17 20:40:04
【问题描述】:

到目前为止,我已经看到有 setTimeout(),process.nextTick(function) 用于异步功能,但是我不知道如何使用它。我已经尝试过我的代码,因为我现在需要一个异步函数,但它会有 Can't set headers after they are sent.

这是我的代码:

var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/myproject';

var updateRecord = function(db, req, callback) {
db.collection('documents').updateMany({ 'Item Description': 
req.body.itemDescrip }, {
    $set: { 'Issued QTY': req.body.issueQty }
}, function(err, results) {
    if (err) return callback(err);
    console.log('Done');
    console.log(results);
    var cursor = db.collection('documents').find({
        'Item Description': req.body.itemDescrip,
        'Issued QTY': req.body.issueQty
    });
    var temp = [];
    cursor.each(function(err, doc) {
        if (err) {
            return callback(err);
        } else{
        console.log('Successfully queried');
        console.log(doc);
        temp.push(JSON.stringify(doc));
        }
    });
    callback(null, temp);
});
};

 module.exports = {
    postCollection: function(req, res) {
    var issueQty = req.body.issueQty;
    var itemDescrip = req.body.itemDescrip;
    MongoClient.connect(url, function(err, db) {
        if(err) {
          res.send(err);
          res.end();
          db.close();
          return;
        }
        updateRecord(db, req, function(err, doc) {
            if(err){
              res.send(err);
            }
            else{
              //setTimeout(function(){
                  res.send(doc);
            //},2000);
            }
            res.end();
            db.close();
        });

    });
 }
}

基本上我正在尝试实现一个异步函数,以便它首先执行updateRecord,然后在下面发送响应,因为现在没有setTimeout,我得到它[],因为两者同时执行。这适用于我正在通过邮递员测试的 web api。任何帮助表示赞赏,谢谢!

更新: 终于成功了!但是我的输出中包含\,这很奇怪,因为我没有将\放入数据库中。这是根据下面的 Roman Maksimov 代码。

[
  "{\"_id\":\"18A\",\"Inventory for NTA SAM Cards\":\"\",\"Item Description\":\"Auresys EZL Prod\",\"Corrupted QTY\":\"\",\"Closing QTY\":\"100\",\"Remarks\":\"\",\"Opening QTY\":\"1000\",\"Issued QTY\":\"100\"}",
  "{\"_id\":\"20\",\"Inventory for NTA SAM Cards\":\"\",\"Item Description\":\"Auresys EZL Prod\",\"Corrupted QTY\":\"\",\"Closing QTY\":\"100\",\"Remarks\":\"\",\"Opening QTY\":\"1000\",\"Issued QTY\":\"100\"}",
  "null"
]

【问题讨论】:

    标签: javascript node.js mongodb asynchronous


    【解决方案1】:

    cursor.each 是异步的,因此,在其中包含回调可能会产生意想不到的结果。

    实现你想要的更简单的方法是从光标中删除each函数并使用mongodb的toArray方法。在 toArray 回调中添加最终回调

    var cursor = db.collection('documents').find({
      'Item Description': req.body.itemDescrip,
      'Issued QTY': req.body.issueQty
    }).toArray(function(err, docs) {
      if (err) {
        return callback(err);
      }
      return callback(null, docs)
    });
    

    【讨论】:

    • 很好的答案!根据您所说的,通常您如何决定将哪个函数用于cursor.eachtoArray
    • 我不确定。但是,如果您希望以 Array 方式获得结果,则 toArray 似乎适用。我不确定each 的用例,因为我还不如只使用 JavaScript 的数组方法来操作结果。
    【解决方案2】:

    看来你是在Node.js 下做的(我说的对吗?)。从您的描述来看,您并不清楚您真正想要达到什么。但是,很明显,您不能将正文发送到响应,因为您已经结束了它(从此时起,响应已经发送到客户端,当然,不可能写入它)。试试这个:

    updateRecord(db, req, function(err, doc) {
        if(err){
            res.send(err);
            res.end();
        } else {
            setTimeout(function(){
                res.send(doc);
                res.end();
            }, 2000);
        }
        db.close();
    });
    

    【讨论】:

    • 嘿,感谢您的帮助,但我不确定我的代码到底出了什么问题。你的意思是问题出在db.close() 上吗?并希望在我的输出中澄清\ 。非常感谢您帮助我解决这个问题。
    • 没有。我的意思是问题出在res.end()。由于您已结束响应,因此您无法写入。
    • 哦,我明白了。感谢您的澄清。我明白你的意思。
    • 关于\。这是temp.push(JSON.stringify(doc)); 的结果,您正在将结果转换为 JSON 字符串。因此,因此,您会得到转义的引号。尝试添加源对象,像这样temp.push(doc);
    • 没有。这就是JSON.stringify() 方法的工作原理。 developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
    猜你喜欢
    • 2020-10-17
    • 2013-01-06
    • 2020-10-04
    • 2022-08-19
    • 2012-01-20
    • 2021-03-27
    • 2014-06-21
    • 1970-01-01
    • 2021-08-20
    相关资源
    最近更新 更多