Как избежать использования setTimeout для ожидания разрешения Promises?

1

У меня есть subreddit, где я хочу разбирать комментарии всех ежедневных потоков. Для этого мне нужно получить идентификаторы потоков. Я использую snoowrap как обертку api.

Мне тяжело обертывать вокруг асинхронного характера узла. Когда я вызываю subreddit.search({query: 'Daily General Discussion - ' + date}), я получаю Promise.

Затем я разрешаю обещание получить идентификатор потока и перенаправить его в новый массив (я попытался сохранить значение с помощью arr[i] = a[0].id, но только последний результат был сохранен в моем массиве, что указывает на то, что Promise.resolve вызывается после цикла for for).

Как остановить остальную часть моего кода до выполнения обещания? Использование setTimeout кажется неэффективным и ненадежным, поскольку время разрешения может быть больше, чем мое время setTimeout.

Код ниже работает, я просто хочу избежать использования setTimeout.

const subreddit = reddit.getSubreddit('subreddit')

let numberOfDaysBack = 50;
let arrIds           = new Array(0);

for (var i = 0; i < numberOfDaysBack; i++) {
  let date        = moment().subtract(0+i, 'days').format('MMMM D, YYYY')
  let dailyThread = subreddit.search({query: 'Daily General Discussion - ' + date})

  Promise.resolve(dailyThread).then(a=>{
    arrIds.push(a[0].id)
  })
}

setTimeout(function(){
  console.log(arrIds)
},1000)

doOtherStuff(arrIds)
  • 0
    @PatrickEvans Можете ли вы подробно изложить это со мной на моем примере? В настоящее время я использую Promise.resolve().then()
  • 0
    The code below works, I just want to avoid using setTimeout. - дождаться обещания решить
Показать ещё 2 комментария
Теги:
promise

4 ответа

3
Лучший ответ

Сопоставьте обещания в массиве, а затем используйте Promise.all() чтобы запускать их одновременно. then вы получите результаты, then того как все обещания будут решены.

const subreddit = reddit.getSubreddit('subreddit')

let numberOfDaysBack = 50
let arrIds

let promises = Array(numberOfDaysBack)
  .fill()
  .map((_, i) => {
    let date        = moment().subtract(0+i, 'days').format('MMMM D, YYYY')
    let dailyThread = subreddit.search({query: 'Daily General Discussion - ' + date})
    return dailyThread
  })

Promise
  .all(promises)
  .then(results => {
    arrIds = results.map(result => result.id)
    doOtherStuff(arrIds)
  });
  • 0
    Обещания не «бегут».
  • 0
    @ shawon191 Я не думаю, что могу получить доступ к arrIds вне области обратного вызова then ().
Показать ещё 5 комментариев
1

Предполагая, что subreddit.search возвращает обещание

const subreddit = reddit.getSubreddit('subreddit')

let numberOfDaysBack = 50;

Promise.all(Array.fill(numberOfDaysBack).map((unused, i) => {
    let date        = moment().subtract(0+i, 'days').format('MMMM D, YYYY')
    return subreddit.search({query: 'Daily General Discussion - ' + date}).then(a => a[0].id);
})).then(results => {
    // here results is the array of "a[0].id"
});
// out here, don't expect to access results without using kludges
// so do it all in the '.then'
  • 0
    Понимаю. Спасибо за объяснение, я надеялся получить доступ к результатам за пределами блока then (), но это не похоже на то, что это возможно.
1

Сохраните все ваши обещания в массиве, а затем используйте Promise.all:

const subreddit = reddit.getSubreddit('subreddit')

let numberOfDaysBack = 50;
let idPromises       = [];

for (var i = 0; i < numberOfDaysBack; i++) {
  let date        = moment().subtract(i, 'days').format('MMMM D, YYYY')
  let dailyThread = subreddit.search({query: 'Daily General Discussion - ' + date})
  idPromises.push(dailyThread.then(a => a[0].id));
}

Promise.all(idPromises).then(arrIds => {
  console.log(arrIds)
});
1

Вы можете использовать Promise.all() в этом случае, когда вам нужно создать список обещаний и дождаться завершения всех этих действий.

const subreddit = reddit.getSubreddit('subreddit');

const numberOfDaysBack = 50;
const arrIds = new Array(0);
const promises = [];

for (var i = 0; i < numberOfDaysBack; i++) {
  const date = moment().subtract(0+i, 'days').format('MMMM D, YYYY');
  const dailyThread = subreddit.search({query: 'Daily General Discussion - ' + date});

  promises.push(dailyThread);
}

Promise.all(promises).then(function(results){
  results.forEach(function(a){
    arrayIds.push(a[0].id);
  });

  console.log(arrayIds);
});

Ещё вопросы

Сообщество Overcoder
Наверх
Меню