节点 JS returns 在异步 json 调用中未定义

Node JS returns undefined within async json call

我有一个异步函数,它在 api 连接到时调用。这应该 return 一些 json 然后它将显示在页面的 json 响应中。在 json 响应中,我未定义。

这是我使用的代码:

const express = require('express');
const router = express.Router();

const superagent = require('superagent'); 

function getCyrpto(){
    var result;
    superagent.get('https://min-api.cryptocompare.com/data/v2/pair/mapping/exchange?e=Kraken')
    .query({ api_key: 'xxxxxxxx'})
    .end((err, res) => {
      if (err) { return console.log(err); }

      result = res.body;

    });
    setTimeout(() => {
        console.log(result);
        return result;
    }, 2000)

}


router.get('/', (req, res, next) => {
    crypto=getCyrpto()

    setTimeout(()=> {
        res.status(200).json({
        message: 'geting cyrpto',
        apiResponse: crypto
    });

    }, 2500)



});  

之所以发生,是因为您的 setTimeOut 方法在您的 api 调用获取结果并将其分配给 result 之前运行。 这是我们大多数人在开始学习并发概念时面临的常见问题。

例如:

console.log("a");
setTimeOut(()=>console.log("b"),1000);
console.log("c");

以上函数的输出将

a
c
b

这是因为 setTimeout 函数是一个承诺,这意味着您的 nodejs 不会在 运行 下一行之前等待它完成,它只会在后台处理 setTimeout 函数以及何时完成它将在 setTimeOut 中调用作为第一个参数给出的回调函数。

你的解决方案应该是

function getCyrpto(){
return new Promise((resolve,reject)=>{
     var result;
    superagent.get('https://min-api.cryptocompare.com/data/v2/pair/mapping/exchange?e=Kraken')
    .query({ api_key: 'xxxxxxxx'})
    .end((err, res) => {
      if (err) { console.log(err); reject(err); }
      result = res.body;
      setTimeout(() => {
        console.log(result);
        resolve(result);
    }, 2000)
    });
  }

   router.get('/', (req, res, next) => {
     getCyrpto().then(crypto=>{
          setTimeout(()=> {
        res.status(200).json({
        message: 'geting cyrpto',
        apiResponse: crypto
    },2500);
  }).catch(err=>{res.status(400).json(err)})
}