Nodejs Обещание. Все с цепочкой обещаний? - PullRequest
0 голосов
/ 06 января 2020

Я не уверен, как задать этот вопрос, но у меня есть ряд обещаний, которые необходимо решить, так как они являются запросами данных 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 часах поиска в Google, но не совсем понял, что я здесь делаю не так.

Ответы [ 4 ]

0 голосов
/ 06 января 2020

Я пытался перенастроить вашу логику c на обещания - один из инструментов, которые вы можете использовать для цепочки зависимых обещаний, - объявить переменные перед обещанием, а затем установить их в .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
});
0 голосов
/ 06 января 2020

NodeJS в неблокирующем режиме. Все строки выполняются синхронно, и dependent определенно не определен в вызове Promise.all, поскольку для него установлено значение undefined в строке let dependent;

.then обратный вызов выполняется асинхронно, например, после весь синхронный код.

Если вы хотите использовать dependent, который разрешен в then, то вам нужно связать then вызовы.

0 голосов
/ 06 января 2020

Я бы рефакторинг с async / await. Чтобы добиться параллелизации, которую вы ищете, мы создаем два обещания (userInfo и зависимые) и затем используем обещание. Все, чтобы дождаться их разрешения. promise.All возвращает массив результатов всех обещаний.

Обязательно используйте попытку, поймайте

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;
    });
}
0 голосов
/ 06 января 2020

Вы можете сделать это с необработанными обещаниями, но это довольно уродливо. Гораздо аккуратнее с асинхронным ожиданием:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...