У меня есть 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)
Сопоставьте обещания в массиве, а затем используйте 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)
});
Предполагая, что 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'
Сохраните все ваши обещания в массиве, а затем используйте 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)
});
Вы можете использовать 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);
});
Promise.resolve().then()
The code below works, I just want to avoid using setTimeout.
- дождаться обещания решить