【问题标题】:Should I be using process.nextTick我应该使用 process.nextTick
【发布时间】:2016-03-30 14:11:12
【问题描述】:

我正试图弄清楚何时使用 process.nextTick。下面我使用异步库来控制我的代码流,并且想知道我是否应该在结束回调中调用 nextTick。

async.parallel([
    function (callback) {
        // do something
        callback(data);
    },
    function (callback) {
        // do something
        callback(data);        
    }
], 
// callback
function (data) {
    process.nextTick(function () {
        // do something
    });
});

【问题讨论】:

  • 是什么让你觉得你应该在那里打电话给nextTick
  • 我读过这个article about nextTick,其中的一个例子是关于使回调异步的。所以我想知道我是否应该考虑在所有回调中使用 nextTick 以避免服务器负载过重时可能出现的未来问题。我的测试在使用和不使用 nextTick 的情况下都能正常工作 - 所以在最好的时候仍然试图绕开我的脑袋。
  • 其实很简单。仅当您希望将某些代码的执行推迟到当前回调完成执行并且所有已排队的回调都已运行之后,才使用nextTick

标签: node.js asynchronous


【解决方案1】:

在不确切知道您的“做某事”是什么的情况下,我认为在这种情况下您没有任何理由需要使用nextTick。当您有理由将函数的执行推迟到事件循环的下一次迭代时,您可以使用nextTick。您可能想阅读Understanding process.nextTick 了解更多详情。

另外,请注意异步的 parallel 任务完成回调接受参数 err, data,所以你应该这样做:

async.parallel([
    function (callback) {
        // do something
        callback(null, data);
    },
    function (callback) {
        // do something
        callback(null, data);        
    }
], 
// callback
function (err, data) {
    if (err) throw err;
    // do something
});

主要区别在于,如果其中一个并行任务返回错误(使用真实的第一个参数调用 callback),则会立即调用最终回调。

【讨论】:

  • 我确实有一个问题 - 如果有回调,调用是否会自动异步?是否所有回调都放入节点事件循环中,或者是否存在仅具有回调不会使节点异步进程的情况?
  • 不一定。回调只是一个“稍后”调用的函数——它本质上没有什么特别之处;这只是简单的函数调用,并且不会在事件循环上自动安排回调(实际上,这就是您可能使用nextTick 的目的)。当然,“稍后”的含义完全取决于您将回调传递给的函数。例如,function (cb) { cb(); } 不是异步的,因为您知道回调将在同一个调用堆栈上以及在事件循环的同一次迭代中立即被调用。
  • ... 这不一定是坏事:考虑一个从数据库中检索数据的函数,但也缓存数据。 function get(key, cb) { if(cache[key]) cb(cache[key]); else getFromDb(key, function(dbresult) { cache[key]=dbresult; cb(dbresult); }); } 如果数据被缓存,该函数同步返回数据(这很好:它使你的程序更快),或者如果它需要从数据库中获取数据,则异步 .
  • 谢谢,这是有道理的。但是节点如何决定将什么放在事件循环中,什么不放在?是否只有 IO 或 nexttick 包装的进程被放入循环中。例如,如果我有一组 5 个回调(一个调用另一个),它们是否都是同步调用的,除非我使用 Nexttick 或进行 IO 调用?
  • 一般情况下,在另一个线程上发生的任何事情(如 I/O)或传递给 nextTicksetTimeoutsetInterval 的回调都会排队等待事件循环的下一次运行.
【解决方案2】:

我的经验是,要让async.parallel 和其他类似功能正常工作,您需要 使所有任务绝对异步;我喜欢异步库,它是我对 Promise 等的第一选择,但如果你不强制任务异步,可能会出现一些奇怪的行为。

请看这里: https://github.com/caolan/async#common-pitfalls-stackoverflow

应该是这样的:

async.parallel([

function(cb){
   process.nextTick(function(){
          doSomePotentiallySyncThing(cb);
   });
},

function(cb){
   process.nextTick(function(){
          doSomePotentiallySyncThing(cb);
   });
},
function(cb){

     definitelyAsync(cb);  // if it's **definitely** async, then we don't need process.nextTick

}
], function complete(err, results){

    // we are in the final callback

});

我对此有 99% 的把握。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 2015-07-26
    • 2011-12-26
    • 2014-07-11
    相关资源
    最近更新 更多