从嵌套异步函数调用返回谓词



我需要过滤一个数组,这取决于通过从外部API检索数据获得的每个元素的子元素是否符合标准。

代码可能比解释更清楚:

//Suppose there is an array filled
//_.filter(array, predicate)
var filtered_array = _.filter(array,function(element){
   //Async operation
   webservices.doStuff(element, function(sub_element){
        //This return is meant for the filter, but returns on .doStuff callback
       return sub_element.thing === "ok";
   });
});

这里的问题是,我不知道如何在这里返回谓词的结果,因为webservices.doStuff是异步的!

任何想法?

你应该看看async.js库https://github.com/caolan/async,它可以做很多异步请求,并在所有请求完成时发出一个回调,并为你提供所有结果的列表,然后你可以应用你的过滤功能。我不记得你可以马上提供一个谓词函数来描述最终结果集中应该有哪些结果,但是如果库不支持的话,它应该能够做这样的事情,而不需要太多的工作。

查看async.js文档中的filter函数

我会使用Q或async来做到这一点。考虑以下示例,您将每个web服务调用包装在一个承诺中,并定义另一个承诺,该承诺将在所有承诺都解决时被解决。然后根据逻辑筛选结果(即所有调用的所有返回的数组)。

 var source = [{a : 1}, {a:2}...] // your data
 var all = Q.all(source.map((o) => Q.Promise((resolve, reject,notify) 
                   => webService.doStuff(o, resolve, reject))))
 all.then((ret) => _.filter(ret.data, (elem) => elem.thing === "ok"))
    .then((filtered) => ... // do something with filtered )

很可能你的web服务代理已经绑定了Q或其他承诺库。这样你的代码就更简单了,像这样:

var all = Q.all(source.map(webService.doStuff))
           .then(filter).then(process)

或者至少你可以把它重构成那么简单。

总的来说,由于node.js环境的非阻塞-接受-回调-离开的性质,掌握一个承诺库或另一个承诺库是必不可少的,asyncQ是我所知的最流行的两个。

(更新:现在它似乎是蓝鸟,它也是最快的。)

使用它们中的任何一个都可以让您在处理异步调用时更容易设计。

最新更新