вернуть обещание текущего асинхронного вызова - PullRequest
0 голосов
/ 23 ноября 2018

Я пытаюсь запустить одновременно много асинхронных функций.Некоторые из них делают http-вызовы, и я, очевидно, не хочу делать один и тот же вызов несколько раз.Итак, как это можно сделать с помощью обещаний ES6, а если нет, какой механизм вы бы порекомендовали для решения подобных ситуаций.

Пример проблемы:

const func1 = () => async1();

const func2 = () => async2().then(async1);

return Promise.all([func1(), func2()]);

async1 и async2являются асинхронными функциями, возвращающими обещания.Проблема заключается в том, как справиться с тремя ситуациями:

  • func1 и func2 запускают async1 одновременно
  • func2 запускает async1, в то время как async1 - это текущий асинхронный вызов в func2
  • async1 запускается func2 после того, как async1 уже был разрешен func1

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

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Вы можете повторно использовать объект обещания в любое время, поэтому, если вы сохраняете обещание запроса при первом его вызове, вы можете вернуть сохраненное обещание при последующих вызовах и избежать нескольких запросов к одному и тому же ресурсу

const async1 = (() => {
  let promise;

  return (arg) => {
    console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
    promise = promise || new Promise((res) => setTimeout(res, 500));
    return promise.then(()=>arg);
  }

})()

Promise.all([async1(1),async1(2)]).then(res=>console.log(res))
0 голосов
/ 23 ноября 2018

Если я правильно понимаю, вы хотите убедиться, что async1 в вашем примере не будет вызываться дважды.

Простой и (довольно низкий) уровень достижения этого - памятка .

Скажем, с помощью lodash _.memoize() это будет

const async1 = _.memoize(async1, () => 1)
// wrapping func1 and func2 is not actually required in this case
const func1 = _.memoize(() => async1()); 
const func2 = _.memoize(() => async2().then(async1));
return Promise.all([func1(), func2()]);

Осторожно, поскольку вы не можете прозрачно переключаться с запомненных на _un_memoized реализаций на лету.

[UPD], поскольку запоминание опирается на переданные аргументы, вам может потребоваться передать обратный вызов resolver.Скажем, в вашем случае async1 может либо получить ноль аргументов, либо что-то из предыдущего обещания (при использовании в .then).Таким образом, аргументы различны, но, поскольку мы знаем, что все аргументы не имеют значения, мы можем передать resolver, который возвращает константу в качестве ключа (скажем, '1')

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