Node JS возвращает неопределенное значение в рамках асинхронного вызова c json - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть асинхронная функция, которая вызывается при подключении API. это должно вернуть 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)



});  

1 Ответ

1 голос
/ 25 апреля 2020

Причина, по которой это происходит, потому что ваши методы setTimeOut запускаются до того, как ваш вызов API получит результат и присвоит его result. Это общая проблема, с которой сталкивается большинство из нас, когда мы начинаем изучать концепцию параллелизма.

Например:

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

Вывод вышеуказанной функции будет

a
c
b

this происходит потому, что функция setTimeout - это обещание, которое означает, что ваш nodejs не будет ждать его окончания до 1015 * перед запуском следующей строки, он просто обработает функцию setTimeout в фоновом режиме, а когда он завершит sh, он вызовет его функция обратного вызова, заданная в качестве первого параметра в 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)})
}
...