有条件地在Node中调用异步功能

时间:2012-10-27 03:00:38

标签: node.js asynchronous

我有以下示例代码 - 第一部分可能会导致异步调用 - 无论哪种方式都应该继续。我不能将其余的代码放在异步回调中,因为它需要在条件为false时运行。那怎么做呢?

if(condition) {
    someAsyncRequest(function(error, result)) {
        //do something then continue
    }
}

 //do this next whether condition is true or not

我假设在函数中放置代码可能是在上面的异步调用中调用该函数的方法,如果条件为假则调用else调用 - 但是有没有替代方法要求我在功能中将其分解?

4 个答案:

答案 0 :(得分:7)

我在Node中使用的库通常是Async(https://github.com/caolan/async)。最后我检查了这也支持浏览器,所以你应该能够在你的发行版中npm / concat / minify。如果你只在服务器端使用它,你应该考虑https://github.com/continuationlabs/insync,这是一个略微改进的Async版本,删除了一些浏览器支持。

我在使用条件异步调用时使用的一种常见模式是使用我想要按顺序使用的函数填充数组并将其传递给async.waterfall。

我在下面列举了一个例子。

var tasks = [];

if (conditionOne) {
    tasks.push(functionOne);
}

if (conditionTwo) {
    tasks.push(functionTwo);
}

if (conditionThree) {
   tasks.push(functionThree);
}

async.waterfall(tasks, function (err, result) {
    // do something with the result.
    // if any functions in the task throws an error, this function is 
    // immediately called with err == <that error>
});

var functionOne = function(callback) {
    // do something
    // callback(null, some_result);
};

var functionTwo = function(previousResult, callback) {
    // do something with previous result if needed
    // callback(null, previousResult, some_result);
};

var functionThree = function(previousResult, callback) {
    // do something with previous result if needed
    // callback(null, some_result);
};

当然你可以使用promises代替。在任何一种情况下,我都希望通过使用async或promises来避免嵌套回调。

你可以通过不使用嵌套回调来避免的一些事情是变量碰撞,提升错误,向右“行进”&gt; &GT; &GT; &gt;,难以阅读代码等。

答案 1 :(得分:3)

只需在需要时声明要运行的其他函数:

var otherFunc = function() {
   //do this next whether condition is true or not
}

if(condition) {
    someAsyncRequest(function(error, result)) {
        //do something then continue

        otherFunc();
    }
} else {
    otherFunc();
}

答案 2 :(得分:3)

只是另一种方法,这就是我抽象模式的方式。可能有一些库(promises?)处理同样的事情。

function conditional(condition, conditional_fun, callback) {
    if(condition)
        return conditional_fun(callback);
    return callback();
}

然后在代码中你可以写

conditional(something === undefined,
            function(callback) {
               fetch_that_something_async(function() {
                  callback();
               });
            },
            function() {

                       /// ... This is where your code would continue


             });

答案 3 :(得分:0)

我建议使用clojurescript,它有一个很棒的core-async库,在处理异步调用时可以让生活变得非常轻松。

在你的情况下,你会写这样的东西:

(go
  (when condition
    (<! (someAsyncRequest)))
  (otherCodeToHappenWhetherConditionIsTrueOrNot))

注意go宏将导致主体异步运行,<!函数将阻塞,直到异步函数返回为止。由于<!函数位于when条件内,因此只有在条件为真时才会阻塞。