簡體   English   中英

如何在Node.js中使用Promise對API進行遞歸請求?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM