You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS中如何让代码在所有request异步请求完成后再执行

问题原因

你遇到的问题是因为request库默认是回调式异步非阻塞接口,遍历发起请求时JS不会等待回调函数执行,就会直接运行后续的console.log("the end")逻辑。

解决思路

将所有异步请求包装为Promise对象,再通过Promise.all批量等待所有异步任务执行完成后再执行打印逻辑。

改造后的完整代码
// 原项目的API_KEY、urlTelegram、NUMERO_DE_ELEMENTOS全局变量保持不变即可
function getValoresAcao(acoes) {
  // 把每个股票的请求任务转为Promise,收集为任务数组
  const requestTasks = acoes.map(acao => getValorAcao(acao));
  // 等待所有任务执行完成
  Promise.all(requestTasks)
    .then(() => {
      console.log("the end");
    })
    .catch(err => {
      console.error("部分请求执行出错:", err);
    });
}

function getValorAcao(acao) {
  // 把整个异步逻辑包装为Promise返回
  return new Promise((resolve, reject) => {
    const url = 'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&parse_mode=HTML&symbol='+acao+'&apikey='+API_KEY;
    request(url, { json: true }, (err, res, body) => {
      if (err) {
        console.log(err);
        return reject(err);
      }

      let contador = 0;
      let valorDeDoisDias = [];

      const dailyJsonObject = body["Time Series (Daily)"];
      const objectKeysArray = Object.keys(dailyJsonObject);
      objectKeysArray.forEach(function(objKey) {
          const objValue = dailyJsonObject[objKey];
          if (contador < NUMERO_DE_ELEMENTOS ) 
          {
            const valorFechamento = objValue["4. close"];
            console.log(valorFechamento);
            contador = contador + 1;
            valorDeDoisDias.push(valorFechamento);
          }
      });

      const textoDiferenca = getDiferencaEmPorcentagem(valorDeDoisDias);

      const bigString = "" + acao + " | " + valorDeDoisDias[0] + " | " + textoDiferenca;
      request(urlTelegram + bigString, { json: true }, (err, res, bodyTelegram) => {
        if (err) {
          console.log(err);
          return reject(err);
        }
        console.log(bodyTelegram);
        // 该股票的所有逻辑处理完成,标记当前Promise完成
        resolve();
      });
    });
  });
}

function getDiferencaEmPorcentagem(valprDeDoisDias) {
  let myString = "";
  const valorDiaAnterior = valprDeDoisDias[0];
  const valorDiaMaisRecente = valprDeDoisDias[1];
  myString = (valorDiaAnterior - valorDiaMaisRecente ) / valorDiaMaisRecente * 100;
  myString = myString.toFixed(2);
  console.log(myString);
  return myString + "%";
}
可选优化:async/await 写法

如果运行环境支持ES7的async/await语法,getValoresAcao可以改写为更简洁的版本:

async function getValoresAcao(acoes) {
  try {
    const requestTasks = acoes.map(acao => getValorAcao(acao));
    await Promise.all(requestTasks);
    console.log("the end");
  } catch (err) {
    console.error("部分请求执行出错:", err);
  }
}
注意事项

如果希望某一个请求出错时不影响其他请求的等待逻辑,可以在getValorAcao的Promise内部捕获错误后直接resolve,避免Promise.all直接中断执行。


内容的提问来源于stack exchange,提问作者fabiobh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:06:03