[英]How to do recursive requests to an API with promise in Node.js?
我需要從API讀取數據,該數據每次查詢僅提供100個結果,以及從何處獲取下一個100的時間戳。
我設法用下面的代碼一個接一個地執行多個請求,但是由於某種原因,它從未返回到最初的承諾。 它被卡在“不再需要獲取任何訂單”上。
app.get('/test', (req, res) => {
const getOrders = (from) => {
return request(mcfApiUrl + "changes?created_after_ts="+from+"&key="+mcfKey)
.then(xml => convert.xmlDataToJSON(xml,{explicitArray:false,mergeAttrs:true}))
.then(orders => checkForMore(orders));
}
const checkForMore = (orders) => {
return new Promise((resolve, reject) => {
if (orders['Orders']['orders'] == 100){
getOrders(orders['Orders']['time_to']);
console.log("Fetched "+ orders['Orders']['orders']+" orders");
console.log("More orders available from: "+moment(orders['Orders']['time_to']*1000).format());
}
else {
console.log("Fetched "+ orders['Orders']['orders']+" orders");
console.log("No more orders to fetch");
resolve(orders);
}
});
};
var fromdate = 1483999200;
getOrders(fromdate)
.then(output => res.send("Done")) // It never gets here
.catch(err => console.log(err));
});
我想念什么?
您的問題是您沒有解決所有選項的checkForMore
承諾。
const checkForMore = (orders) => {
return new Promise((resolve, reject) => {
if (orders['Orders']['orders'] == 100){
getOrders(orders['Orders']['time_to']); // <-- not resolved
}
else {
resolve(orders);
}
});
};
只需將對getOrders
的調用包裝為resolve
解決此問題。
resolve(getOrders(orders['Orders']['time_to']))
但是,您實際上並不需要創建新的承諾:
const checkForMore = (orders) =>
orders['Orders']['orders'] == 100
? getOrders(orders['Orders']['time_to'])
: Promise.resolve(orders);
實際上,您的整個功能可以縮小為幾行:
const getOrders = (from) =>
request(mcfApiUrl + "changes?created_after_ts="+from+"&key="+mcfKey)
.then(xml => convert.xmlDataToJSON(xml,{explicitArray:false,mergeAttrs:true}))
.then(orders =>
orders.Orders.orders == 100
? getOrders(orders.Orders.time_to)
: Promise.resolve(orders)
);
現在,如果要累積所有訂單,則需要通過遞歸級別維護某些狀態。
您可以使用全局狀態或其他參數來執行此操作:
const getOrders = (from, allOrders = []) =>
// ^ accumulation container
request(mcfApiUrl + "changes?created_after_ts="+from+"&key="+mcfKey)
.then(xml => convert.xmlDataToJSON(xml,{explicitArray:false,mergeAttrs:true}))
.then(orders => {
allOrders.push(orders); // <-- accumulate
return orders.Orders.orders == 100
? getOrders(orders.Orders.time_to, allOrders) // <-- pass through recursion
: Promise.resolve(allOrders)
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.