簡體   English   中英

從嵌套的異步函數調用返回謂詞

[英]Return predicate from nested async function call

我需要過濾一個數組,具體取決於通過從外部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或異步來做到這一點。 考慮下面的示例,您將每個Web服務調用包裝在一個Promise中,並定義在所有Promise都解決后將要解決的另一個Promise。 然后根據邏輯過濾結果(即所有調用的所有返回的數組)。

 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或另一個Promise庫綁定。 因此,您的代碼將變得更加簡單,例如:

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

或者至少您可以將其重構為如此簡單。

總體而言,由於node.js環境的非阻塞性,接受和執行性質,掌握一個或另一個承諾庫至關重要,據我所知, asyncQ是最受歡迎的兩個。

更新 :現在它似乎是藍鳥,而且它也是最快的。)

擁有它們中的任何一個都可以使您在處理異步調用時提出更簡單的設計。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM