2017-05-12 68 views
0

您好我試圖讓50毫秒之前下一個http請求是服務器,但也想實現一些功能,當所有的請求已經完成。如何讓循環http請求延遲,但也使用Promise.all來檢測何時完成請求

我舉了一個例子來說明我想要做什麼。

所以下面是我的例子快遞API

app.get('/morans/test', (req, res) => { 
    console.log(`start test request`); 
    let targetUrl = `http://-domain-/solr/genea_expression/smplGeoclust?q=text:"GO:0003674"&stats.facet=geohash_3&rows=10320`; 
    let i = 0; 
    let promises = []; 

    console.log(`making request ${i}`); 


    for (let i = 0; i < 200; i++) { 
     setTimeout(
      () => { 
       let testReq = new Promise((resolve, reject) => { 
        http.get(targetUrl, (result) => { 
         result.on('data', (chunk) => { 
          console.log(`working ${i}`); 
         }).on('end',() => { 
          console.log(`ending ${i}`); 
         }).on('error', (err) => { 
          console.log(`this is error message ${err}`); 
         }) 
        }) 
       }); 

       promises.push(testReq); 
      }, 50 * i 
     ) 
    } 
    Promise.all(promises).then(() => { 
     console.log(`done`); 
    }); 
}); 

延遲正常工作;但是,Promise.all(promises)...正在發生過早觸發(第一次請求發出後立即觸發console.log('done'))。當沒有超時時它工作正常,所以我認爲setTimeout沒有足夠的時間將承諾推送到promises陣列。如何編寫一個代碼,以便每隔50ms發出一次http請求,但是也知道所有請求何時成功返回?

回答

2

由於所有超時都沒有過期,所以您一次打電話給Promise.all,因爲您的promises數組爲空。

你可以動議Promise.all打電話給你的超時回調裏面,push之後,檢查數組的長度:

for (let i = 0; i < 200; i++) { 
    setTimeout(
     () => { 
      // ...etc ... etc 
      promises.push(testReq); 
      if (promises.length == 200) { // <---- add this block 
       Promise.all(promises).then(() => { 
        console.log(`done`); 
       }); 
      } 
     }, 50 * i 
    ) 
} 

另外,還要確保你打電話resolve()new Promise回調中,否則你的諾言會留未決:

    .on('end',() => { 
         console.log(`ending ${i}`); 
         resolve(); 
        }) 

documentation on http.get來看看如何真正得到響應數據......這將是有意義的調用resolve與該數據作爲參數。

+0

謝謝!奇蹟般有效。還要感謝有關'resolve()'的大熱門。我把它放在了我的實際API上,但忘了放在測試API中。非常感謝您的幫助! – forJ