我正在使用Robinhood-node 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
结果之前,无法调用后续网址。这导致我创建了一个回调地狱:-( order - > url - > url - > url ...
我无法在循环中调用url
方法。循环在回调执行之前继续执行。
如何反复拨打url
?到目前为止,我使用递归函数调用来管理hack。这是我的代码 - https://gist.github.com/lordloh/f5c8c589b4538ab9674db919ae2e2834
我正在学习节点js ...: - /
答案 0 :(得分:1)
您是否考虑过使用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);
}
}
答案 1 :(得分:0)
嗯,我们假设我们有一个名为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
轻松添加一些限制或设置限制。