在 for 循环中使用异步/承诺/回调的最佳方法

如何解决在 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 函数中发生的事情:

  1. 您开始遍历 data.USDTPairs 数组,选择第一个元素
  2. 你打电话给binance.prevDay。这还什么都不做,因为它是一个需要一些时间的异步函数。值得注意的是,尚未向 downStocks 添加任何数据。
  3. 继续执行 1-2,仍然没有添加任何数据
  4. 您返回 downStocks,它仍然是空的。
  5. 你的功能完成了,你打印空数组

现在,在某个时刻,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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?