我正在尝试构建服务器,该服务器将从外部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会有所帮助,但不会出现同样的问题。有什么想法应该以正确的方式完成吗?
答案 0 :(得分:2)
在第二个文件(服务器)中,您这样写:
return new Promise(function(resolve, reject) {
let data = new Data();
resolve(data.array);
});
好吧,我怀疑基于第一个文件,数据构造函数正在调用“异步”功能:
this.checkIfPageExists();
此函数正在调用axios.get,我认为这是一个承诺,并且构造函数的执行在checkIfPageExists响应之前继续进行,基本上是在编写时在第二个文件中进行
let data = new Data();
resolve(data.array);
正在执行解析而没有响应。
您需要重写此逻辑,以等待承诺解决/拒绝。
例如:
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);
})
});
}
但这只是一个例子,也许您应该总体上检查代码的结构以适应它。
在简历中,只要不执行表示http请求永不响应的res.send()函数,您就始终等待诺言响应。