为什么打印我从循环中获得api呼叫的null值

发布于 2025-01-21 19:41:40 字数 946 浏览 4 评论 0原文

硬币列表是加密硬币的数组([“ Btcusdt”,...])。我尝试使用GetRSI的GetPriceAction和RSI获取价格,而这两个功能在尝试控制数据时正在起作用。但是,当我尝试在循环完成后打印响应时。它打印空数组,长度为此数组的0。我想将数据对象(由符号,收盘价和RSI组成)作为响应数组中的元素

 import { COIN_LIST } from "./COIN_LIST.js";
    import { getPriceAction } from "./PRICE_ACTION.js";
    import { getRSI } from "./RSI.js";

async function main() {
  try {
    let response = await [];
    await COIN_LIST.forEach((element, i) => {
      setTimeout(() => {
        let data = { symbol: element };
        getPriceAction(element, "4h").then((res) => {
          data.closingPrice = res;
          getRSI(res).then((res) => {
            data.RSI = res.reverse();
            data.closingPrice = data.closingPrice.reverse();
            response.push(data);
            console.log(data)
          });
        });
      }, i * 1000);
    });
    console.log(response);
  } catch (error) {
    console.log(error.message);
  }
}
main();

COIN LIST is an array of crypto coins(["BTCUSDT",...]). I try to get the price using getPriceAction and RSI from getRSI and these two functions are working when I try to console DATA. But when I try to print the response after the completion of the loop. It prints the empty array and the length is 0 of this array. I want to store the DATA object (consisting of SYMBOL, closing price and RSI) as an element in the response array

 import { COIN_LIST } from "./COIN_LIST.js";
    import { getPriceAction } from "./PRICE_ACTION.js";
    import { getRSI } from "./RSI.js";

async function main() {
  try {
    let response = await [];
    await COIN_LIST.forEach((element, i) => {
      setTimeout(() => {
        let data = { symbol: element };
        getPriceAction(element, "4h").then((res) => {
          data.closingPrice = res;
          getRSI(res).then((res) => {
            data.RSI = res.reverse();
            data.closingPrice = data.closingPrice.reverse();
            response.push(data);
            console.log(data)
          });
        });
      }, i * 1000);
    });
    console.log(response);
  } catch (error) {
    console.log(error.message);
  }
}
main();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小猫一只 2025-01-28 19:41:40

如果您想适当地使用async/等待代码,请使用异步/等待,请勿使用

然后SettieMout增加了几秒钟...仅在一个结果后等待1秒钟才能获得下一个结果 - 更清洁,如果一个请求碰巧需要更长的时间,您将不会一次获得两个请求(这可能是一个问题如果API的速率有限)

。然后 ...使用async/等待或。然后/<代码> .catch - 在一个函数中非常罕见的两个函数

都不使用async/等待 ... ,并且在A 中创建一系列承诺数组。Foreach非常天真,您也可以使用.map而不是!然后,您可以等待Promise.All(xxx.map(.....)) - 但这对于并发请求很有用,而不是像您的代码这样的串行请求,等待

import { COIN_LIST } from "./COIN_LIST.js";
import { getPriceAction } from "./PRICE_ACTION.js";
import { getRSI } from "./RSI.js";

async function main() {
    try {
        const wait = (ms) => new Promise(resolve => setTimeout(resolve, 1000));
        let response = []; //---> don't need that `await`
        for (let element of COIN_LIST) {
            let data = { symbol: element };
            data.closingPrice = await getPriceAction(element, "4h");
            const res = await getRSI(data.closingPrice);
            data.RSI = res.reverse();
            data.closingPrice = data.closingPrice.reverse();
            response.push(data);
            console.log(data);
            await wait(1000);
        }
        console.log(response);
    } catch (error) {
        console.log(error.message);
    }
}
main();

等待等待(1000)可以根据API的速率限制进行调整...如果速率限制适用于请求时,则可以对请求之间的延迟进行明智的函数。

该代码以此方式假定速率限制是基于先前对下一个请求的响应之间的时期。

If you want to use async/await properly for your code, then use async/await, don't use .then/.catch as well

Some notable changes

there is no setTimeout of increasing seconds ... just waiting 1 second after one result before getting the next - far cleaner, and if one request happens to take a lot longer, you won't end up with two requests at once (which may be an issue if the API is rate limited)

no .then ... use async/await OR .then/.catch - very rare to need both in the one function

don't use forEach with async/await ... it never does what you want, and creating an array of Promises inside a .forEach is extremely naive, you may as well use .map instead! then you can await Promise.all(xxx.map(.....)) - but that's useful for concurrent requests, not so much for serial requests like your code does

import { COIN_LIST } from "./COIN_LIST.js";
import { getPriceAction } from "./PRICE_ACTION.js";
import { getRSI } from "./RSI.js";

async function main() {
    try {
        const wait = (ms) => new Promise(resolve => setTimeout(resolve, 1000));
        let response = []; //---> don't need that `await`
        for (let element of COIN_LIST) {
            let data = { symbol: element };
            data.closingPrice = await getPriceAction(element, "4h");
            const res = await getRSI(data.closingPrice);
            data.RSI = res.reverse();
            data.closingPrice = data.closingPrice.reverse();
            response.push(data);
            console.log(data);
            await wait(1000);
        }
        console.log(response);
    } catch (error) {
        console.log(error.message);
    }
}
main();

the await wait(1000) could be tweaked depending on the rate limiting of the API ... if the rate limit applies to when the request is made, you could make a function that is smart about the delay between requests.

The code this way assumes the rate limit is based on the period between previous response to next request.

樱花落人离去 2025-01-28 19:41:40

循环完成后,承诺尚未得到解决,这就是为什么它打印一个空数组的原因。
实现所需的一种方法是使用等待(...),或等待所有承诺得到解决,然后打印结果。

import { COIN_LIST } from "./COIN_LIST.js";
import { getPriceAction } from "./PRICE_ACTION.js";
import { getRSI } from "./RSI.js";

async function main() {
  try {
    let response = []; //---> don't need that `await`
    const promises = []; //---> array of promises
    COIN_LIST.forEach((element, i) => {
      setTimeout(() => {
        let data = { symbol: element };
        const promise = getPriceAction(element, "4h").then((res) => {
          data.closingPrice = res;
          getRSI(res).then((res) => {
            data.RSI = res.reverse();
            data.closingPrice = data.closingPrice.reverse();
            response.push(data);
            console.log(data)
          });
        });
        promises.push(promise) //---> save the reference to a promise
      }, i * 1000);
    });
    await Promise.all(promises) //---> await for all promises to be resolved, then print the result
    console.log(response);
  } catch (error) {
    console.log(error.message);
  }
}
main();

After the completion of the loop, the promises didn't get resolved yet, that's why it print an empty array.
One way to achieve what you need is using await for(...), or wait for all promises to be resolved, and then print the results.

import { COIN_LIST } from "./COIN_LIST.js";
import { getPriceAction } from "./PRICE_ACTION.js";
import { getRSI } from "./RSI.js";

async function main() {
  try {
    let response = []; //---> don't need that `await`
    const promises = []; //---> array of promises
    COIN_LIST.forEach((element, i) => {
      setTimeout(() => {
        let data = { symbol: element };
        const promise = getPriceAction(element, "4h").then((res) => {
          data.closingPrice = res;
          getRSI(res).then((res) => {
            data.RSI = res.reverse();
            data.closingPrice = data.closingPrice.reverse();
            response.push(data);
            console.log(data)
          });
        });
        promises.push(promise) //---> save the reference to a promise
      }, i * 1000);
    });
    await Promise.all(promises) //---> await for all promises to be resolved, then print the result
    console.log(response);
  } catch (error) {
    console.log(error.message);
  }
}
main();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文