我正在尝试构建从外部 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/