如何解决在 for 循环中使用异步/承诺/回调的最佳方法
我正在构建一个交易机器人,它需要从不同的文件中获取股票名称。但即使我在我的代码中使用了 async 函数和 await,这也不起作用。
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
我的 getDownTrendeingStock 文件
const init = async () => {
const symbols = await getDownTrendingStock();
console.log("All stocks that are down: " + symbols);
const doOrder = async () => {
//do stuff
}
doOrder();
}
我也尝试在 for 循环中使用异步,因为 getDownTrendinStock 函数在 for 循环完成之前返回一个空数组。我没有找到正确的方法来做到这一点,因为我对所有异步、承诺和回调的东西感到困惑。在这种情况下使用的正确语句是什么?
输出:
const downStocks = []
function getDownTrendingStock () {
for(i = 0; i < data.USDTPairs.length; i++){
const USDTPair = data.USDTPairs[i] + "USDT";
binance.prevDay(USDTPair,(error,prevDay,symbol) => {
if(prevDay.priceChangePercent < -2){
downStocks.push(symbol)
}
});
}
return downStocks;
}
想要的输出:
All stocks that are down:
解决方法
我认为您发布的代码中的主要问题是您混合了回调和承诺。
这就是您的 getDownTrendingStock
函数中发生的事情:
- 您开始遍历
data.USDTPairs
数组,选择第一个元素 - 你打电话给
binance.prevDay
。这还什么都不做,因为它是一个需要一些时间的异步函数。值得注意的是,尚未向downStocks
添加任何数据。 - 继续执行 1-2,仍然没有添加任何数据
- 您返回
downStocks
,它仍然是空的。 - 你的功能完成了,你打印空数组
现在,在某个时刻,nodejs event loop 会继续并开始处理您之前通过调用 binance.prevDay
创建的异步任务。在内部,它可能会调用 API,这需要时间;调用完成后,它会调用您提供的函数,该函数将数据推送到 downStocks
数组。
总而言之,您没有等待异步代码完成。您可以通过多种方式实现这一目标。
一种是将其包装在一个承诺中,然后等待该承诺:
const result= await new Promise((resolve,reject) => {
binance.prevDay(USDTPair,(error,prevDay,symbol) => {
if (error) {
reject(error);
} else {
resolve({prevDay,symbol});
}
});
});
if(result.prevDay.priceChangePercent < -2){
downStocks.push(result.symbol)
}
请注意,您可能也可以为此使用 promisify。此外,这意味着您将在开始下一个请求之前等待一个请求完成,这可能会大大减慢您的代码速度,具体取决于您需要多少次调用;您可能还想查看 Promise.all。
,一般来说,我使用两种技术:
const asyncFunc = () => {smthAsync};
const arrayToProcess = [];
// 1
const result = await arrayToProcess.reduce((acc,value) => acc.then(() => asyncFunc(value)),Promise.resolve(someInitialValue));
// 2
// here will be eslint errors
for(let i = 0 i < arrayToProcess.length; i+=1) {
const processResult = await asyncFunc(value);
// do with processResult what you want
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。