如何正确处理 Promise.all:未定义
Posted
技术标签:
【中文标题】如何正确处理 Promise.all:未定义【英文标题】:How to handle Promise.all properly: Getting undefined 【发布时间】:2018-05-23 18:11:22 【问题描述】:我正在尝试从向不同 REST API 发出的一些请求中获取一个填充了信息的数组。
我曾想过使用Promise.all
来做到这一点,但由于某种原因,它会产生一个内部包含一堆undefined
的数组。
[未定义,未定义,未定义,未定义]
这是我的代码:
var _ = require("lodash");//Used exclusively to check if the result from the request is an object
var ccxt = require("ccxt");//External library used to make the requests
let pairs = ["ETH/EUR", "BTC/EUR", "LTC/EUR", "BCH/EUR"]; //Array on which the Promise.all is based
function test(p)
for (var i = 0; i < ccxt.exchanges.length; i++) //Looping through all the rest APIs
let exchange = new ccxt[ccxt.exchanges[i]](); //Defining each API to make the requests
if (exchange.hasFetchOrderBook)
exchange //Beginning of the request
.fetchOrderBook(p)
.then(order =>
if (_.isObject(order) && order.bids[0][1])
let now = Math.floor(new Date());
order.mkt = exchange.name;
order.pair = p;
order.ping = now - order.timestamp;
return order; //Return the result of the request
)
.catch(e => );
Promise.all(pairs.map(test)) //Making the requests based on the Pairs Array
.then(res =>
console.log(res); //Logging the results ==> [undefined, undefined, undefined, undefined] for some reason...
)
.catch(e =>
console.log(e);
);
我知道请求是正确发出的,因为如果我在循环中 console.log 记录 order
,我会得到正确的结果——记录时的结果示例:
bids:
[ [ 12009.52, 0.0468 ],
[ 12008.5, 0.0227 ],
[ 12007.48, 30.9321 ],
[ 12006.46, 0.0537 ],
[ 12005.45, 0.0157 ],
[ 12004.43, 7.1659 ],
[ 12003.41, 0.0164 ],
[ 12002.39, 23.4159 ],
[ 12001.38, 0.0284 ],
[ 12000.36, 0.0132 ],
[ 11999.34, 0.0194 ],
[ 11998.33, 0.0034 ],
[ 11997.31, 7.526 ],
[ 2445.72, 34.075 ],
[ 2445.17, 25.4842 ],
[ 2444.96, 0.1118 ],
[ 2444.75, 23.288 ],
[ 2444, 0.0247 ],
[ 2443.8, 0.192 ],
[ 765.51, 0.0828 ] ],
asks:
[ [ 12048.74, 2.523 ],
[ 12049.77, 0.0159 ],
[ 12050.79, 0.029 ],
[ 12051.82, 0.0061 ],
[ 12052.84, 0.0181 ],
[ 12053.87, 0.0164 ],
[ 12054.89, 0.0355 ],
[ 12055.92, 0.0042 ],
[ 13419.62, 0.0063 ],
[ 13420.64, 0.0174 ],
[ 13421.78, 0.0143 ],
[ 13422.92, 0.026 ],
[ 13424.06, 0.0055 ],
[ 13425.2, 14.4552 ],
[ 13426.23, 0.0065 ],
[ 13427.25, 0.0057 ],
[ 13428.39, 0.0147 ],
[ 13429.53, 4.0375 ],
[ 13430.56, 23.9541 ],
[ 13431.58, 0.0137 ] ],
timestamp: 1512845715447,
datetime: '2017-12-09T18:55:15.447Z',
mkt: 'LakeBTC',
pair: 'BTC/EUR',
ping: 0
所以我想我正在处理的问题与函数的异步特性有关......但我不确定如何让它同步。 再次,只是为了澄清我的问题:目标是获得一个包含 4 种不同类型对象的数组(每对一个 --> 数组),以便我可以对每个对象进行操作。 为了更清楚起见,这里是我要实现的目标的说明:
[
[
Object1,
Object2,
Object3,
etc...
],
[
Object1,
Object2,
Object3,
etc...
],
[
Object1,
Object2,
Object3,
etc...
],
[
Object1,
Object2,
Object3,
etc...
]
]
为什么Promise.all
不等待请求结果就返回数组?
我希望这已经足够清楚了!如果不让mw知道! :P
提前感谢您的帮助!
【问题讨论】:
您的函数test
不会返回任何内容,因此 undefined
。
嘿@elclanrs!它不返回订单吗? --> return order; //Return the result of the request
那个return
是inside另一个函数,所以它返回到那个函数,而不是外部那个。
【参考方案1】:
您的test
函数确实返回undefined
。您需要为结果返回一个承诺:
function test(p)
return Promise.all(ccxt.exchanges.map(api => //Looping through all the rest APIs
//^^^^^^^^^^^^^^^^^^
let exchange = new ccxt[api](); //Defining each API to make the requests
if (exchange.hasFetchOrderBook)
return exchange //Beginning of the request
.fetchOrderBook(p)
.then(order =>
if (_.isObject(order) && order.bids[0][1])
let now = Math.floor(new Date());
order.mkt = exchange.name;
order.pair = p;
order.ping = now - order.timestamp;
return order; //Return the result of the request
// else undefined
)
.catch(e => ); // undefined
// else undefined
));
当然,当if
条件不适用或发生错误时,您的承诺仍会通过undefined
实现。
【讨论】:
以上是关于如何正确处理 Promise.all:未定义的主要内容,如果未能解决你的问题,请参考以下文章