Нужно ли заключать обещание в функцию? - PullRequest
0 голосов
/ 27 августа 2018

У меня такая ситуация:

import processAsyncCall from "../helpers/processAsyncCall";

const promiseWrapper = () => new Promise((res, rej) => { /* [1] */ });
const onResolve = () => { /* [2] */ };

dispatch(processAsyncCall(promiseWrapper, onResolve));
  1. promiseWrapper содержит обещание, которое будет выполнено при выполнении определенного действия (например: получить файл, обновить содержимое и т. Д.).
  2. Этот метод будет вызван, когда promise внутри promiseWrapper разрешится.

Давайте посмотрим на processAsyncCall.

export default (
  promiseWrapper,
  onResolve = null,
) => (dispatch, getState) => {
  dispatch(showLoading());
  promiseWrapper()
    .then(result => {
      if (onResolve !== null && typeof onResolve === "function") {
        onResolve(dispatch, getState)(result);
      }
    })
    .catch(() => console.log("ERROR_IN_ASYNC"))
    .finally(() => dispatch(hideLoading()));
  });
};

Важная часть promiseWrapper().then(result => { /* ... */}).

Я выполняю функцию promiseWrapper, чтобы создать Обещание на месте .


Мой вопрос:

Обязательно ли заключать обещание в функцию, чтобы убедиться, что оно не разрешено до его обработки?

У меня была такая проблема, когда обратный вызов then не работал бы, если бы я непосредственно передал Promise в качестве параметра.

dispatch(processAsyncCall(new Promise(/* ... */), /* ... */));

Насколько я понимаю, когда обещание разрешает , вызывается обратный вызов then. Но если функция разрешается и в это время отсутствует обратный вызов then, то Promise равно выполнено / выполнено / мертво .

Имейте в виду, что приведенный выше пример довольно прост, но в некоторых случаях Promise создается в другом месте и передается до достижения функции processAsyncCall.

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Я чувствую, что поведение Promise остается немного загадочным в вашем уме.

Вы можете представить Обещание как объект, имеющий 4 свойства:

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

state всегда начинается с pending, и код внутри вашего обещания составляется для вызова в следующем цикле выполнения, как если бы вы вызывали его с помощью setImmediate.

Обещание может быть разрешено или отклонено только один раз и останется в этом состоянии навсегда после этого.

Когда обещание разрешено / отклонено, его состояние меняется на fulfilled или rejected, и соответствующие обратные вызовы вызываются по порядку.

Когда вы набираете then или catch в Обещании, если состояние Обещания pending, обратный вызов добавляется в соответствующий список. Если обещание уже разрешено (соответственно отклонено), обратный вызов будет вызван в следующем цикле выполнения.

Надеюсь, это поможет вам понять, что здесь происходит.

0 голосов
/ 27 августа 2018

Насколько я понимаю, когда обещание разрешается, тогда вызывается обратный вызов. Но если функция разрешается, и тогда нет обратного вызова, Обещание выполнено / выполнено / не работает.

Это неверно. По определению, код не может знать , когда обещание будет разрешено, и требование кода для присоединения обратного вызова до , которое он разрешает, наложит значительные ограничения на обещания и сделает их гораздо менее полезными. Нет, вы можете присоединить новый обратный вызов в любое время, и он будет называться:

const p = new Promise(r => {
    r('yay');
    setTimeout(() => p.then(console.log));
});

p.then(console.log);

Разница в вашем случае, вероятно, заключается просто в том, ожидает ли processAsyncCall обещание в качестве аргумента или функцию, которая возвращает обещание. Это разные типы, и, очевидно, с ними нужно обращаться по-разному.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...