如何让javascript承诺与node+;是否在EJS文件上显示?
在说要看医生之前,我已经看过了,他们一点帮助都没有 我有一个以节点为主干的网页。在一个页面上,我需要从NASA的天文学每日图片(APOD)API中获取过去的10幅图像,然后,我需要从发射库API()中获取接下来的5次发射。我的问题是并非所有APOD都会加载(我理解这一点是因为异步请求的性质) 以下是我针对节点后端的简明app.js文件:如何让javascript承诺与node+;是否在EJS文件上显示?,javascript,html,node.js,asynchronous,ejs,Javascript,Html,Node.js,Asynchronous,Ejs,在说要看医生之前,我已经看过了,他们一点帮助都没有 我有一个以节点为主干的网页。在一个页面上,我需要从NASA的天文学每日图片(APOD)API中获取过去的10幅图像,然后,我需要从发射库API()中获取接下来的5次发射。我的问题是并非所有APOD都会加载(我理解这一点是因为异步请求的性质) 以下是我针对节点后端的简明app.js文件: app.get("/index", function(req, res) { /**Requesting NASA's Astronomy Pictur
app.get("/index", function(req, res) {
/**Requesting NASA's Astronomy Picture of the Day**/
var apod_url = "https://api.nasa.gov/planetary/apod?api_key=[My Key]"
var apod_img_urls = [];
var curr_moment = moment();
for(var i = 0; i < 10; i++) {
var appended_url = apod_url + "&date=" + curr_moment.subtract(i, "days").format("YYYY-MM-DD");
request(appended_url, function(error, reponse, body) {
if(!error && reponse.statusCode == 200) {
var img_json = JSON.parse(body);
if(img_json.media_type == "image") {
var apod_promise = new Promise(function(resolve, reject){
resolve(img_json.hdurl);
});
apod_img_urls.push(apod_promise);
}
} else {
console.log(error);
}
});
}
/**************************************************/
var url = "https://launchlibrary.net/1.3/launch?next=20&mode=verbose";
request(url, function(error, response, body) {
if(!error && response.statusCode == 200) {
var data = JSON.parse(body);
res.render("index", {data: data, apod_img_urls: apod_img_urls});
} else {
console.log(error);
}
});
});
app.get(“/index”),函数(req,res){
/**请求NASA提供当天的天文图片**/
var apod_url=”https://api.nasa.gov/planetary/apod?api_key=[我的钥匙]”
var apod_img_url=[];
var curr_矩=矩();
对于(变量i=0;i<10;i++){
var added_url=apod_url+“&date=“+curr_moment.subtract(i,“days”).格式(“YYYY-MM-DD”);
请求(附加的url、函数(错误、响应、正文){
如果(!error&&reponse.statusCode==200){
var img_json=json.parse(body);
if(img_json.media_type==“image”){
var apod_promise=新承诺(函数(解析、拒绝){
解析(img_json.hdurl);
});
apod_img_url.push(apod_promise);
}
}否则{
console.log(错误);
}
});
}
/**************************************************/
变量url=”https://launchlibrary.net/1.3/launch?next=20&mode=verbose";
请求(url、函数(错误、响应、正文){
如果(!error&&response.statusCode==200){
var data=JSON.parse(body);
res.render(“索引”{data:data,apod_img_url:apod_img_url});
}否则{
console.log(错误);
}
});
});
下面是一个EJS代码段
<% apod_img_urls.forEach(function(promise, index) { %>
<div class="carousel-item <%= (index == 0 ? 'active' : '') %>">
<div class="w-100 home-image" style="background-image: url('<%= promise.then(function(url) {return url}); %>')"></div>
</div>
<% }); %>
当我签入源代码时,它显示div的背景图像url是[objectpromise]。按照我的方式,没有图像显示。此外,显示的div数量(即我应该拥有的图像数量)是可变的;有时候是5,有时候是3,有时候是零。我的问题是在另一个请求中呈现页面吗?另外,我如何才能获得实际的图像URL以显示在EJS文件中?您创建承诺太晚了,在对reequest的异步回调中-需要相当简单的代码重组 一旦所有承诺都在一个数组中,您就需要使用Promise.all等待它们完成
app.get("/index", function(req, res) {
/**Requesting NASA's Astronomy Picture of the Day**/
var apod_url = "https://api.nasa.gov/planetary/apod?api_key=[My Key]"
var promises = [];
var curr_moment = moment();
for(var i = 0; i < 10; i++) {
var appended_url = apod_url + "&date=" + curr_moment.subtract(i, "days").format("YYYY-MM-DD");
promises.push(new Promise((resolve, reject) => {
request(appended_url, function(error, reponse, body) {
if(!error && reponse.statusCode == 200) {
var img_json = JSON.parse(body);
resolve(img_json.hdurl);
} else {
reject(error);
console.log(error);
}
});
}));
}
Promise.all(promises).then(apod_img_urls => {
var url = "https://launchlibrary.net/1.3/launch?next=20&mode=verbose";
request(url, function(error, response, body) {
if(!error && response.statusCode == 200) {
var data = JSON.parse(body);
res.render("index", {data, apod_img_urls});
} else {
console.log(error);
}
});
});
});
现在,您的代码可以写成:
app.get("/index", function(req, res) {
/**Requesting NASA's Astronomy Picture of the Day**/
const apod_url = "https://api.nasa.gov/planetary/apod?api_key=[My Key]"
const curr_moment = moment();
Promise.all(Array.from({length:10}, (_, i) => {
const appended_url = apod_url + "&date=" + curr_moment.subtract(i, "days").format("YYYY-MM-DD");
return requestP(appended_url).then(({response, body}) => JSON.parse(body).hdurl);
})).then(apod_img_urls => {
const url = "https://launchlibrary.net/1.3/launch?next=20&mode=verbose";
return requestP(url).then(({response, body}) => {
const data = JSON.parse(body);
return res.render("index", {data, apod_img_urls});
});
});
});
注意:这里有很多ES2015+正在进行中如果您使用像
请求承诺
这样的承诺返回请求库,那么您可以执行以下操作:
app.get("/index", function(req, res) {
var apod_url = "https://api.nasa.gov/planetary/apod?api_key=[My Key]"
var curr_moment = moment();
var urls = [];
for(var i = 0; i < 10; i++) {
urls[i] = apod_url + "&date=" + curr_moment.subtract(i, "days").format("YYYY-MM-DD");
}
Promise.all(urls.map(url => rp({ url, json: true})).then((results) => {
// here you have all results with JSON already parsed for you
// ...
}).catch((err) => {
// handle error
// make sure to return response to client
// ...
});
// ...
});
然后使用Promise.all
等待它们全部完成,同时执行:
Promise.all(promises)
.then(...)
.catch(...);
或者,如果您使用的是async/await,则:
try {
let x = await Promise.all(promises);
...
} catch (err) {
...
}
许多模块,如axios
或request-promise-json
或request-promise
都将为您解析json,如果您正确运行,请参阅:
JSON.parse()
放在try/catch
(或使用我的小模块)的内部-查看这些答案以了解原因:
Promise.all(promises)
.then(...)
.catch(...);
try {
let x = await Promise.all(promises);
...
} catch (err) {
...
}