简体   繁体   English

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

[英]Conditionally call async function in Node

I have the following example code - the first part can result in an async call or not - either way it should continue. 我有以下示例代码 - 第一部分可以导致异步调用 - 无论哪种方式它应该继续。 I cannot put the rest of the code within the async callback since it needs to run when condition is false. 我不能将其余的代码放在异步回调中,因为它需要在条件为false时运行。 So how to do this? 那怎么做?

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

 //do this next whether condition is true or not

I assume that putting the code to come after in a function might be the way to go and call that function within the async call above or on an else call if condition is false - but is there an alternative way that doesn't require me breaking it up in functions? 我假设在函数中放置代码可能是在上面的异步调用中调用该函数的方法,或者在条件为假的情况下在else调用上调用该函数 - 但是有一种替代方法不需要我破坏它在功能上?

A library I've used in Node quite often is Async ( https://github.com/caolan/async ). 我在Node中使用的库经常是Async( https://github.com/caolan/async )。 Last I checked this also has support for the browser so you should be able to npm / concat / minify this in your distribution. 最后我检查了这也支持浏览器,所以你应该能够在你的发行版中npm / concat / minify。 If you're using this on server-side only you should consider https://github.com/continuationlabs/insync , which is a slightly improved version of Async, with some of the browser support removed. 如果你只在服务器端使用它,你应该考虑https://github.com/continuationlabs/insync ,这是一个稍微改进的Async版本,删除了一些浏览器支持。

One of the common patterns I use when using conditional async calls is populate an array with the functions I want to use in order and pass that to async.waterfall. 我在使用条件异步调用时使用的常见模式之一是使用我想按顺序使用的函数填充数组并将其传递给async.waterfall。

I've included an example below. 我在下面列举了一个例子。

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);
};

Of course you could use promises instead. 当然你可以使用promises代替。 In either case I like to avoid nesting callbacks by using async or promises. 在任何一种情况下,我都希望通过使用async或promises来避免嵌套回调。

Some of the things you can avoid by NOT using nested callbacks are variable collision, hoisting bugs, "marching" to the right > > > >, hard to read code, etc. 你可以通过不使用嵌套回调来避免的一些事情是变量冲突,提升错误,“行进”到右边>>>,>难以读取代码等。

Just declare some other function to be run whenever you need it : 只需在需要时声明一些其他函数即可运行:

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();
}

Just an another way to do it, this is how I abstracted the pattern. 只是另一种方法,这就是我抽象模式的方式。 There might be some libraries (promises?) that handle the same thing. 可能有一些库(promises?)处理相同的事情。

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

And then at the code you can write 然后在代码中你可以写

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

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


             });

I would recommend using clojurescript which has an awesome core-async library which makes life super easy when dealing with async calls. 我建议使用clojurescript ,它有一个很棒的核心异步库,在处理异步调用时可以让生活变得非常轻松。

In your case, you would write something like this: 在你的情况下,你会写这样的东西:

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

Note the go macro which will cause the body to run asynchronously, and the <! 注意go宏会导致主体异步运行,而<! function which will block until the async function will return. 函数将阻塞,直到异步函数返回。 Due to the <! 由于<! function being inside the when condition, it will only block if the condition is true. 函数在when条件内,只有在条件为真时才会阻塞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM