如何处理节点中的递归回调

How do I deal with recursive callback in node?

本文关键字:递归 回调 节点 何处理 处理      更新时间:2023-09-26

我正在使用罗宾汉节点API来检索我的证券投资组合。我使用的API有两个函数-

orders(callbackfn)

检索最近的100个订单和到下一页的链接。

url(url,callback)

获取下一页100多个订单。

这两个函数返回的JSON看起来像-

{
    results:[
        {order 0},
        {order -1},
        ...
        {order -100}],
    next: url_for_next_page
}

现在,我需要将下一个url传递给url函数以获得另外100个订单。最后一页有next: null

url不能被调用,直到我处理orders的结果。在处理之前的url结果之前,不能调用后续的url。这导致我创建了一个回调地狱:-(order -> url -> url -> url…

不能在循环中调用url方法。循环在回调执行之前继续执行。

如何重复调用url ?到目前为止,我已经使用递归函数调用管理了一个hack。这是我的代码- https://gist.github.com/lordloh/f5c8c589b4538ab9674db919ae2e2834

我正在学习节点js作为我去…: -/

您考虑过使用Promises来避免回调地狱吗?

我看了一下你的代码,我用Promises:

想象一下这样的东西
const credentials = {
    username: 'username',
    password: 'Password'
};
const Robinhood = require('../robinhood-node/src/robinhood');
function orderHandler(orderArray,allOs){
    return new Promise((resolve, reject) => 
    {       
        for (let i = 0; i < orderArray.length; i++) {
            var e = orderArray[i];
            var ss = e.instrument.split('/');
            var instrument = ss[ss.length-2];
            allOs.push({'id':e.id,
              'instrument':instrument,
              'quantity':e.quantity,
              'price':e.average_price,
              'side':e.side,
              'transaction_time':e.last_transaction_at
            });
        }
        resolve(allOs);     
    });
}
Robinhood(credentials, () => 
{
  Robinhood.orders(function(e,r,b){   
    orderHandler(b.results,[]).then((allOs) => 
    {
        urlSequence(b.next, allOs).then((allOS) => csv(allOs));             
    });
  });       
});
function urlSequence(url,allOs){
    if(!url)
        return Promise.resolve(allOS);
    return new Promise((resolve, reject) =>
    {
        Robinhood.url(url, (e,r,b) => 
        {
            orderHandler(b.results, allOS)
                .then((allOs) => {
                    setTimeout(() => resolve(urlSequence(b.next, allOs)), 0);                       
                });     
        });     
    });
}
function csv(Arr){
    var A;
    for (var i=0;i<Arr.length;i++){
        A=Arr[i];
        console.log(A.id+", "+A.instrument+", "+A.quantity+", "+A.price+", "+A.quantity+", "+A.side+", "+A.transaction_time);
    }
}

假设我们有一个名为fetch的函数它所做的就是获取一些数据并将其传递给回调函数,下面是它的实现方式:

function getAllPages(url, callback) {
  // This is a function that returns a function:
  const getPage = (oldData) => (response) => {
    // We concat the data from the response to our collected list:
    const newData = oldData.concat(response.results)
    if(response.next && response.next.length) {
      // Call the function returned by getPage passing in newData
      // This is what we call recursion
      fetch(response.next, getPage(newData))
    } else {
      // If there is no next page we just pass all the collected data to a callback:
      callback(newData)
    }
  }
  // We pass it an empty list as initial data:
  getPage([])({next: url, results: []})
}
getAllPages('some url...', (data) => {
  console.log(data)
})

我希望这会对你有所帮助。

如果页面太多,您可以使用setTimeout轻松地添加一些限制或设置限制。