javascript - Node API等待外部数据

标签 javascript json node.js express promise

我正在尝试构建从外部 API 获取数据并将其返回到标准端点 localhost:3000/v1/api/的服务器。问题是获取数据大约需要 2 秒,而我最终总是渲染一个空对象。

我有 2 个文件。第一个 data.js 是从使用 axios 的外部 api 获取数据,如下所示:

const axios = require('axios');

class Data {
  constructor() {
    this.array = [];
    this.checkIfPageExists();
  }

  get array() {
    if (this.array.length > 0) {
      return this.array;
    }
  }

  checkIfPageExists() {
    axios.get('http://external.api.address/status')
    .then(response => {
      if (response.status === 200) {
         this.fetchData();
      }
     })
  }

  fetchData() {
    axios.get('http://external.api.address/data')
    .then(response => {
      if (response.data.length > 0) {
         this.array = response.data;
      }
     })
  }
}

module.exports = Data;

第二个文件是服务器本身,因此我可以将响应呈现给浏览器。

const express = require('express');
const cors = require('cors');
const Data = require('./data');

const port = 8000;
const app = express();

const middleware = (req, res, next) => {
    const myPromise = () => {
        return new Promise(function(resolve, reject) {
            let data = new Data();
            resolve(data.array);
        });
    }

    let promise = myPromise();

    promise.then((data) => {
        if (data) {
            console.log(data)
            res.data = data;
            next();
        }
    })

}

class Server {
    constructor() {
        this.initCORS();
        this.initMiddleware();
        this.initRoutes();
        this.start();
    }

    start() {
        app.listen(port, () => {
            console.log("Listening on port: " + port);
        })
    }

    initCORS() {
        app.use(cors());
    }

    initMiddleware() {
        app.use(middleware);
    }

    initRoutes() {
        app.get("/", (req, res) => {
            res.send(JSON.stringify(res.data, null, '\t'));
        });
    }

}

new Server();

在从外部 API 获取数据之前,我总是得到一个空对象。我认为 Promise 会有所帮助,但不,仍然是同样的问题。有什么想法应该如何以正确的方式完成此操作?

最佳答案

在第二个文件(服务器)中,您编写了以下内容:

return new Promise(function(resolve, reject) {
        let data = new Data();
        resolve(data.array);
    });

好吧,我怀疑根据第一个文件,数据构造函数正在调用“异步”函数:

this.checkIfPageExists();

这个函数正在调用 axios.get,我认为这是一个 promise ,并且构造函数的执行在 checkIfPageExists 响应之前继续,基本上在您编写时的第二个文件中:

let data = new Data();
resolve(data.array);

正在执行解析但没有响应。

您需要重写此逻辑以等待 promise 解析/拒绝。

例如:

const axios = require('axios');
class Data {
  constructor() {
    this.array = [];
    // --- FIX: No check in this line ---
  }

  get array() {
    if (this.array.length > 0) {
      return this.array;
    }
  }

  checkIfPageExists() {
    // return a promise:
    return new Promise((resolve, reject) => {
      axios.get('http://external.api.address/status')
      .then(response => {
        if (response.status === 200) {
           this.fetchData().then(()=>{ resolve(); });
        }
      })
     });
  }

  fetchData() {
    // return the promise:
    return axios.get('http://external.api.address/data')
    .then(response => {
      if (response.data.length > 0) {
         this.array = response.data;
      }
     })
  }
}

module.exports = Data;

在第二个文件中,更改:

const myPromise = () => {
        return new Promise(function(resolve, reject) {
            let data = new Data();
            data.checkIfPageExists().then(()=>{
              resolve(data.array);
            })
        });
}

但这只是一个示例,也许您应该检查一下代码的总体结构以适应它。

在resume中,你总是等待promise响应,只要你不执行表示http请求永远不会响应的res.send()函数。

关于javascript - Node API等待外部数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52653999/

相关文章:

node.js - 具有直通功能的重复 Gulp 乙烯基流 - `TypeError: Invalid non-string/buffer chunk`

javascript - jQuery 跟踪器触发两次

javascript - Angular 插值系统中的点(嵌套)表示法

javascript - 如何将 jQuery .live() 附加到这段代码?

json - 使用 -jsonArray 时 mongoimport 的速度非常慢

node.js - PM2 - 语法错误 : Block-scoped declarations not yet supported outside strict mode

javascript - hapi 在发送响应之前设置 header

javascript - 解释 Javascript 字符串文字中的 HTML 标签

javascript - Json 对象在 IE11 中无法正确获取

json - 在 SoapUI 中将属性作为 JSON 传递