我想不斷從網站同步資料,但我只有 300 個電話/15 分鐘。因此,我認為我可以將所有同步請求(大約 1000 個)放入一個陣列中,然后每 15 分鐘僅決議 300 個,直到請求陣列為空,然后重新開始。但是,當我執行以下操作時:
let requests = []
params = 'invoice-items?invoice_id='
let positions = null
for (const invoice of invoices) {
requests.push(new Promise(async (resolve, reject) => {
positions = await getBillomatData(params invoice.id, null, 0, null)
await updateDatabase(positions, models.billomat.Position)
}))
}
console.log(requests[0])
await requests[0]
console.log(requests[0])
一旦我在 requests[0] 處等待請求,它就會執行所有請求,并且我超過了呼叫限制。
uj5u.com熱心網友回復:
所有異步呼叫都會立即執行,因為 JavaScript 會在處理每個呼叫后立即執行所有代碼。Await 等待結果,它不等待執行。
您需要使用諸如bottleneck 之類的工具來限制您的請求。
每 15 分鐘處理 1000 個請求的 300 個請求將需要一個小時才能完成。這是一個很長的時間來保持節點作業的運行無所作為。
基本限制器可能會在外部檔案或資料庫中跟蹤您要發出的所有請求,然后使用 cron 作業每 15 分鐘執行一次 JavaScript 代碼以處理另外 300 個請求。如果沒有其他請求,您的應用程式可能會終止。但是,只要 cron 作業繼續運行,它就會每 15 分鐘喚醒并運行一次。
uj5u.com熱心網友回復:
最簡單的方法(雖然沒有優化)是
- 批量呼叫 300 個
- 執行一批并等待所有問題都解決,然后再進行下一批
let batch = []
// imagine urls is a array of url of 900 items
urls.map(async (url)=>{
batch.push(somePromiseFuctionToDoTheApiCall(url))
if(batch.length >= 300){
await Promise.all(batch)
// sleep is a promisified settimeout function, ref: https://stackoverflow.com/a/56520579/3359432
await sleep(calculateTimeToWaitBeforeProceedingToNextBatch)
batch = []
}
})
// there might be some leftovers at the end of batch you should process them also
如果您可以使用庫并停止重新發明輪子,那么請查看lodash.chunk, bluebird.map, bluebird.each,bluebird.delay
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/404456.html
標籤:
上一篇:如何同時運行兩部分代碼
