асинхронное ожидание с setInterval - PullRequest
0 голосов
/ 05 сентября 2018
function first(){
  console.log('first')
}
function second(){
  console.log('second')
}
let interval = async ()=>{
  await setInterval(first,2000)
  await setInterval(second,2000)
}
interval();

Представьте, что у меня есть этот код выше.

Когда я запускаю его, first() и second() будут вызываться одновременно; как мне позвонить second() после того, как first)() вернет некоторые данные, например, если first() сделано, только тогда позвонить second()?

Поскольку first() в моем коде будет работать с большим объемом данных, и если эти 2 функции будут вызываться одновременно, это будет трудно для сервера.

Как мне звонить second() каждый раз, когда first() возвращает некоторые данные?

Ответы [ 3 ]

0 голосов
/ 05 сентября 2018

setInterval плохо работает с обещаниями, потому что вызывает многократный обратный вызов, в то время как обещание разрешается один раз.

Похоже, что setTimeout подходит для случая. Он должен быть обещан для использования с async..await:

async () => {
  await new Promise(resolve => setTimeout(() => resolve(first()), 2000));
  await new Promise(resolve => setTimeout(() => resolve(second()), 2000));
}
0 голосов
/ 06 июня 2019

Как упомянуто выше setInterval плохо работает с обещаниями , если вы не остановите его . Если вы очистите интервал, вы можете использовать его как:

async function waitUntil(condition) {
  return await new Promise(resolve => {
    const interval = setInterval(() => {
      if (condition) {
        resolve('foo');
        clearInterval(interval);
      };
    }, 1000);
  });
}

Позже вы можете использовать его как

const bar = waitUntil(someConditionHere)
0 голосов
/ 05 сентября 2018

У вас есть несколько проблем:

  1. Обещания могут быть разрешены только один раз, setInterval() предназначен для вызова обратного вызова несколько раз, Обещания плохо поддерживают этот случай.
  2. Ни setInterval(), ни более подходящие setTimeout() не возвращают Обещания, поэтому await в них бессмысленно в этом контексте.

Вы ищете функцию, которая возвращает Обещание, которое разрешается через несколько раз (используя setTimeout(), возможно, не setInterval()).

К счастью, создание такой функции довольно тривиально:

async function delay(ms) {
  // return await for better async stack trace support in case of errors.
  return await new Promise(resolve => setTimeout(resolve, ms));
}

С помощью этой новой функции delay вы можете реализовать желаемый поток:

function first(){
  console.log('first')
}
function second(){
  console.log('second')
}
let run = async ()=>{
  await delay(2000);
  first();
  await delay(2000)
  second();
}
run();
...