2017-10-20 116 views
1

我有一個subreddit我想解析所有日常線程的評論。要做到這一點,我必須得到線程ID。我使用snoowrap作爲api包裝。如何避免使用setTimeout等待Promise解決?

我在包裝節點的異步性質方面遇到困難。當我打電話給subreddit.search({query: 'Daily General Discussion - ' + date})時,我得到了一個承諾。

然後我解決承諾獲取線程ID並將其推送到一個新的數組(我試着用arr[i] = a[0].id保存值,但只有最後的結果存儲在我的數組中,這表明Promise.resolve被調用後我的循環)。

如何在Promise解決之前停止執行其餘代碼?由於解析時間可能比我的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()' – Huy

+0

'下面的代碼工作,我只是想避免使用setTimeout.' - 等待承諾解決 –

+0

@JaromandaX但是,如果我想使用值該數組爲更多的計算,我如何確保承諾在我執行更多代碼之前得到解決? – Huy

回答

2

將承諾映射到數組中,然後使用Promise.all()同時運行它們。所有承諾解決後,您將在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

承諾不是「運行」。 – Bergi

+0

@ shawon191我不認爲我可以在then()回調的範圍之外訪問arrId。 – Huy

+0

@Huy不,你不能。這不是承諾的設計。你只需在'then'中'doOtherStuff(arrIds)'。 (回答更新) – shawon191

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); 
}); 
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()塊之外的結果,但它看起來不可能。 – Huy