节点 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)})
}
我有一个异步函数,它在 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)})
}