【问题标题】:How to handle risk of multiple callbacks under one function in Nodejs如何处理Nodejs中一个函数下的多个回调风险
【发布时间】:2018-01-06 11:13:28
【问题描述】:

我正在使用 async.map 来处理多个任务,并且对于每个任务,我想设置一个超时时间。

async.map(tasks, handleFunction, (error, callback))

I add the setTimeout inside handleFunction to return immediately,

const handleFunction = function(callback){

setTimeout(()=> {return setImmediate(callback, new Error())});

// handler logic, detail process code ...
// some http requests or file read and 

return callback();
}

以上,返回多个回调是有风险的,一个来自正常流程代码(如果任务完成成功),一个来自setTimeout。

我的问题是:有没有更好的方法来避免这种情况。因为目前的解决方案可能会返回两个回调。我收到以下错误:“回调已被调用。”

【问题讨论】:

  • 你为什么要把setImmediate()放在setTimeout()里面?你希望用它来完成什么?为什么不直接使用setImmediate()?还有,你为什么不指定setTimeout() 的时间?

标签: javascript node.js callback settimeout async.js


【解决方案1】:

你可以设置一个标志来判断你是否已经调用了回调。你可以把它放在你的 async.map() 处理程序中:

let called = false;
function doCallback(err, data) {
   if (!called) {
       called = true;
       callback(err, data);
   }
}

然后,在您的async.map() 处理程序中使用doCallback() 而不是callback()。如果您不止一次拨打doCallback(),它什么也做不了。只有第一次调用它会被传递给实际的异步回调。


如果您展示了包含所有详细信息的实际代码,我们还可以建议一种编码方法,如果您在计时器关闭之前调用回调并且如果计时器确实触发,则在计时器触发之前取消计时器,然后设置一个您已经超时的标志,因此您可以在事情完成后调用callback() 之前检查该标志。


您还可以为自己创建一个回调超时实用程序函数,您可以在任何需要此类功能的地方重复使用它。

// callback that times out
function timerCallback(t, timeoutErr, callback) {
    let called = false;
    let timer = setTimeout(() => {
        if (!called) {
            called = true;
            callback(timeoutErr);
        }
    }, t);
    return function(err, data) {
        clearTimeout(timer);
        if (!called) {
            called = true;
            callback(err, data);
        }
    };
}

然后你会像这样使用它:

async.map(tasks, handleFunction, (error, callback))

    // create callback with debouncing and timeout
    let internalCallback = timerCallback(1000, new Error("timeout"), callback);

    // then do your async stuff and call internalCallback(err, data) when done
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 2017-03-11
    • 1970-01-01
    • 2014-04-10
    • 2013-05-08
    • 2020-06-02
    • 2016-10-02
    相关资源
    最近更新 更多