调用猫鼬保存方法时async.js挂起的瀑布方法

Posted

技术标签:

【中文标题】调用猫鼬保存方法时async.js挂起的瀑布方法【英文标题】:Waterfall method for async.js hanging when calling mongoose save method 【发布时间】:2013-03-14 18:51:22 【问题描述】:

我正在尝试使用async waterfall method,但是当它使用其中一个功能时,它会挂起。我怀疑这是因为 save() 操作对于执行上下文来说太慢了,但这就是我开始使用异步瀑布的原因,所以我可以等待返回的值,直到它进入系列中的下一个函数(传递正确的数据,在我下面的例子中是counted)。

// 在我的用户控制器中:

async.waterfall([
  function(callback) 
    getSubmission(id, function(submission) 
      if (submission) 
        callback(null, submission);
      
    );
  ,
  function(submission, callback) 
    var submissionId = submission._id;

    getViews(submissionId, ip, function(count) 
      if (count) 
        callback(null, count, submissionId);
      
    );
  ,
  // Those top two functions work perfectly passing what
  // I need to this one which is where I'm having trouble
  function(views, submissionId, callback) 
    // addView is called because it is actually
    // inserting a row in the db, but never returns from the caller
      addView(submissionId, ip, function(added) 
        // this callback doesn't fire
        if (added) 
          callback(null, added);
        
      );
  ,
  function(added, callback) 
    console.log(added);
  
 ]);

这就是addView() 的含义(也在用户控制器中,之前的async.waterfall 代码也在其中):

var addView = function(submissionId, ip, callback) 
  Submission.addView(
    submissionId : submissionId,
    ip: ip
  , function(err, counted) 
    if (err) 
      throw err;
    

    if (counted) 
      callback(counted);
    
  );
;

当它调用Submission.addView()时,这就是它所调用的(在我的提交模型文件中):

exports.addView = function(obj, fn) 
  var ip = obj.ip,
      submissionId = obj.submissionId,
      submissionView = new SubmissionView(obj);
// it gets to this point

  submissionView.save(
    ip : ip,
    submission_id : submissionId
  , function(err, counted) 
    fn(err, counted);
  );
;

【问题讨论】:

【参考方案1】:

每当异步“挂起”时,通常是因为尚未调用回调。

您需要确保在所有代码路径中调用回调。我还建议您将任何异步回调的第一个参数保留为错误,即使您不使用它,因为这是整个 node.js 使用的模式。一些模块依赖于这种模式。例如域。

如果您进行以下更改,那么我预计会在某处弹出一些错误:

getSubmission(id, function(submission) 
      if (submission) 
        callback(null, submission);
      
    );

应该是这样的:

getSubmission(id, function(err, submission) 
      if(err)
        return callback(err);
      
      if (!submission) 
        return callback('no submission found');
      
      callback(null, submission);
    );

【讨论】:

原来我将 2 个方法传递给 Mongoose save() 方法,但它只需要一个,所以摆脱我传递的参数修复它。

以上是关于调用猫鼬保存方法时async.js挂起的瀑布方法的主要内容,如果未能解决你的问题,请参考以下文章

ThreadPoolExecutor:拉出挂起的任务

Windows 8/10 API 检测挂起的进程

锁屏后,前台service被挂起的一个解决方法

瀑布流实现思路

wait和notify

Python中的yield和send