簡體   English   中英

Nodejs Promise.All 與承諾鏈?

[英]Nodejs Promise.All with promise chain?

我不知道如何問這個問題,但我有一組承諾都需要解決,因為它們是數據 api 請求,但三個中的一個取決於另一個,我不確定如何解決。

有問題的代碼如下所示:

    let dependent;

    let subscriptions = getSubscriptions() //data fetch
       .then((subscriptions) => {
            let fieldList = subscriptions.reduce((subscription) => {
               if(subscription.Threshold) {
                  return subscription.Threshold.Field;
               }
               return null;
           });
           dependent = getUpdatedInfo(request, body, fieldList); //Data fetch promise
           return subscriptions;
       });

    let userInfo = getUserInformation(); //Data fetch

    Promise.all([subscriptions, userInfo, dependent]).then(function(values) {
        console.log({ promiseAll: values }); //Dependent is always undefined
        processSubscriptions(result, body, userInfo, subscriptions, dependent);
    });

基於過去 4 個小時的谷歌搜索,我已經嘗試了幾種不同的方式來使用此代碼,但還沒有完全弄清楚我在這里做錯了什么。

你可以用原始的 Promise 來做到這一點,但這有點難看。 使用 async/await 更整潔:

async function whatever() {
  const subs = await getSubscriptions();
  const fieldList = subs.reduce((subscription) => {
    if(subscription.Threshold) {
      return subscription.Threshold.Field;
    }
      return null;
    });
  const dependent = await getUpdatedInfo(request, body, fieldList);
  const userInfo = await getUserInfo();
  return processSubscriptions(result, body, userInfo, subscriptions, dependent);
}

非阻塞的 NodeJS。 所有行都是同步執行的,在Promise.all調用中, dependent肯定是 undefined 因為它在Promise.all中設置為undefined let dependent;

.then回調是異步執行的,例如所有同步代碼之后。

如果你想使用dependent它在解決then然后,你必須鏈then調用。

我會用 async/await 重構。 為了實現您正在尋找的並行化,我們為(userInfo 和dependent)創建了兩個promise,然后使用promise.All 等待它們的解決。 promise.All 返回所有承諾結果的數組。

確保使用 try, catch

async function processSubscriptionsHandler(request, body) {
    try {
        let userInfoPromise = getUserInformation(); // async function returning a promise
        let subscriptions = await getSubscriptions()
        let fieldList = getFieldList(subscriptions)
        let dependentPromise = getUpdatedInfo(request, body, fieldList) // async function returning a promise

        let [userInfo, dependent] = await Promise.all([userInfoPromise, dependentPromise]) // await both promises to resolve and map resulting array to variables

        processSubscriptions(result,
            body,
            userInfo,
            subscriptions,
            dependent);
    } catch (e) {
        console.error(e)
    }
}

function getFieldList(subscriptions) {
    subscriptions.reduce((subscription) => {
        if (subscription.Threshold) {
            return subscription.Threshold.Field;
        }
        return null;
    });
}

我試圖將您的邏輯重新整合到承諾中——您可以用於一系列相關承諾的工具之一是在承諾之前聲明您的變量,然后在.then設置它們——這樣變量就可用了對於代碼塊中的所有閉包:

let subscriptions;
let updatedInfo;
let subscriptionsPromise = getSubscriptions() //data fetch
   .then((subscriptionsResults) => {
        let fieldList = subscriptionsResults.reduce((subscription) => {
           if(subscription.Threshold) {
              return subscription.Threshold.Field;
           }
           return null;
       });
       subscriptions = subscriptionsResults
       return getUpdatedInfo(request, body, fieldList); //Data fetch promise
   })
   .then(updatedInfoResult => {
       updatedInfo = updatedInfoResult;
   });

let userInfoPromise = getUserInformation(); //Data fetch

Promise.all([subscriptionsPromise, userInfoPromise]).then(function(values) {
    // at this point, subscriptions should have a value, 
    // and so should updatedInfo,
    // and values[1] should be the result from userInfoPromise
});

暫無
暫無

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

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