在呈现页面之前等待挂起的 Promise
Wait for pending Promises before rendering the Page
我目前正在为 node.js 中的 Twitch 社区开发一个网络项目。我正在使用 Twitch API 接收个人资料图片,并将它们与其他信息一起添加到对象数组中,然后再呈现页面。不幸的是,当页面呈现时,我只会得到个人资料图片 URL 的未决承诺。在页面呈现后将近一毫秒,我得到了关于 PB-Links 的控制台日志,所以它运行得很快,所以我认为 ajax 没有意义。在脚本继续呈现页面之前是否有可能等到承诺加载完毕?
提前致谢
async function getStreamersPB(streamerName){
var streamer = await twitch.getUsers(streamerName);
var streamerPBURL = await streamer.data[0].profile_image_url;
console.log(streamerPBURL);
}
...
router.get('/', (req, res) => {
var streamer = [];
con.query("SELECT * FROM xxx", function (err, result) {
if (err) {
console.log(err);
}
if (result.length !== 0){
for (let i = 0; i < result.length; i++) {
let streamObj = {
"id": result[i].id,
"name": result[i].name,
"website": result[i].website.toLowerCase(),
"status": result[i].status,
"rang": result[i].rang,
"userPB": getStreamersPB(result[i].name)
}
console.log(streamObj);
streamer.push(streamObj);
}}});
con.query("SELECT * FROM xxx WHERE xxx = '" + xxx + "'", function (err, result) {
if (err) {
console.log(err);
} if(result.length === 1){
res.render('home', {
message: result[0].twitchName,
userID: result[0].id,
streamer: streamer
});
...
这是我的控制台日志:
{
id: 1,
name: 'xxx',
website: 'xxx',
status: 0,
rang: 1,
userPB: Promise { <pending> }
}
https://static-cdn.jtvnw.net/...xxx
您可以先使用css隐藏页面,然后当您的个人资料图片加载后,使用javascript更改css并显示页面。
正如 slebetman 所提到的,您必须等待异步函数调用,否则您将向您的客户发送待处理的承诺。这是修改后的代码。
router.get('/', (req, res) => {
var streamer = [];
// This function has been marked as async so we can use await in it.
con.query("SELECT * FROM xxx", async function (err, result) {
if (err) {
console.log(err);
}
if (result.length !== 0) {
for (let i = 0; i < result.length; i++) {
let streamObj = {
"id": result[i].id,
"name": result[i].name,
"website": result[i].website.toLowerCase(),
"status": result[i].status,
"rang": result[i].rang
}
// getStreamersPB is an asynchronous method which you must await.
streamObj.userPB = await getStreamersPB(result[i].name);
console.log(streamObj);
streamer.push(streamObj);
}
}
// I moved this query to inside the callback for the first query
// to ensure this query happens after the first one. Originally,
// both `con.query` calls were being invoked at the same time, so
// there's no garuntee in what order they execute.
con.query("SELECT * FROM xxx WHERE xxx = '" + xxx + "'", function (err, result) {
if (err) {
console.log(err);
} if (result.length === 1) {
res.render('home', {
message: result[0].twitchName,
userID: result[0].id,
streamer: streamer
});
}
});
});
});
由于您收到 Dylan 的回答错误,请将异步添加到第一个 com.query 函数。
router.get('/', async (req, res) => {
var streamer = [];
con.query("SELECT * FROM xxx", async function (err, result) {
if (err) {
console.log(err);
}
if (result.length !== 0){
for (let i = 0; i < result.length; i++) {
let streamObj = {
"id": result[i].id,
"name": result[i].name,
"website": result[i].website.toLowerCase(),
"status": result[i].status,
"rang": result[i].rang
}
// getStreamersPB is an asynchronous method which you must await.
streamObj.userPB = await getStreamersPB(result[i].name);
console.log(streamObj);
streamer.push(streamObj);
}}});
con.query("SELECT * FROM xxx WHERE xxx = '" + xxx + "'", function (err, result) {
if (err) {
console.log(err);
} if(result.length === 1){
res.render('home', {
message: result[0].twitchName,
userID: result[0].id,
streamer: streamer
});
}
我修好了!我忘了在函数中加入 return 语句!
非常感谢大家的回答和帮助!!!
我目前正在为 node.js 中的 Twitch 社区开发一个网络项目。我正在使用 Twitch API 接收个人资料图片,并将它们与其他信息一起添加到对象数组中,然后再呈现页面。不幸的是,当页面呈现时,我只会得到个人资料图片 URL 的未决承诺。在页面呈现后将近一毫秒,我得到了关于 PB-Links 的控制台日志,所以它运行得很快,所以我认为 ajax 没有意义。在脚本继续呈现页面之前是否有可能等到承诺加载完毕?
提前致谢
async function getStreamersPB(streamerName){
var streamer = await twitch.getUsers(streamerName);
var streamerPBURL = await streamer.data[0].profile_image_url;
console.log(streamerPBURL);
}
...
router.get('/', (req, res) => {
var streamer = [];
con.query("SELECT * FROM xxx", function (err, result) {
if (err) {
console.log(err);
}
if (result.length !== 0){
for (let i = 0; i < result.length; i++) {
let streamObj = {
"id": result[i].id,
"name": result[i].name,
"website": result[i].website.toLowerCase(),
"status": result[i].status,
"rang": result[i].rang,
"userPB": getStreamersPB(result[i].name)
}
console.log(streamObj);
streamer.push(streamObj);
}}});
con.query("SELECT * FROM xxx WHERE xxx = '" + xxx + "'", function (err, result) {
if (err) {
console.log(err);
} if(result.length === 1){
res.render('home', {
message: result[0].twitchName,
userID: result[0].id,
streamer: streamer
});
...
这是我的控制台日志:
{
id: 1,
name: 'xxx',
website: 'xxx',
status: 0,
rang: 1,
userPB: Promise { <pending> }
}
https://static-cdn.jtvnw.net/...xxx
您可以先使用css隐藏页面,然后当您的个人资料图片加载后,使用javascript更改css并显示页面。
正如 slebetman 所提到的,您必须等待异步函数调用,否则您将向您的客户发送待处理的承诺。这是修改后的代码。
router.get('/', (req, res) => {
var streamer = [];
// This function has been marked as async so we can use await in it.
con.query("SELECT * FROM xxx", async function (err, result) {
if (err) {
console.log(err);
}
if (result.length !== 0) {
for (let i = 0; i < result.length; i++) {
let streamObj = {
"id": result[i].id,
"name": result[i].name,
"website": result[i].website.toLowerCase(),
"status": result[i].status,
"rang": result[i].rang
}
// getStreamersPB is an asynchronous method which you must await.
streamObj.userPB = await getStreamersPB(result[i].name);
console.log(streamObj);
streamer.push(streamObj);
}
}
// I moved this query to inside the callback for the first query
// to ensure this query happens after the first one. Originally,
// both `con.query` calls were being invoked at the same time, so
// there's no garuntee in what order they execute.
con.query("SELECT * FROM xxx WHERE xxx = '" + xxx + "'", function (err, result) {
if (err) {
console.log(err);
} if (result.length === 1) {
res.render('home', {
message: result[0].twitchName,
userID: result[0].id,
streamer: streamer
});
}
});
});
});
由于您收到 Dylan 的回答错误,请将异步添加到第一个 com.query 函数。
router.get('/', async (req, res) => {
var streamer = [];
con.query("SELECT * FROM xxx", async function (err, result) {
if (err) {
console.log(err);
}
if (result.length !== 0){
for (let i = 0; i < result.length; i++) {
let streamObj = {
"id": result[i].id,
"name": result[i].name,
"website": result[i].website.toLowerCase(),
"status": result[i].status,
"rang": result[i].rang
}
// getStreamersPB is an asynchronous method which you must await.
streamObj.userPB = await getStreamersPB(result[i].name);
console.log(streamObj);
streamer.push(streamObj);
}}});
con.query("SELECT * FROM xxx WHERE xxx = '" + xxx + "'", function (err, result) {
if (err) {
console.log(err);
} if(result.length === 1){
res.render('home', {
message: result[0].twitchName,
userID: result[0].id,
streamer: streamer
});
}
我修好了!我忘了在函数中加入 return 语句!
非常感谢大家的回答和帮助!!!