gpt4 book ai didi

javascript - NodeJS - 如何使 res.render() 在函数之后运行而不是异步运行

转载 作者:行者123 更新时间:2023-12-02 23:01:51 30 4
gpt4 key购买 nike

我制作了一个简单的应用程序,它的 UI 显示一个输入文本和两个按钮:获取和显示。

总体思路是在用户输入一个单词并单击“获取”后该应用程序将从 Datamuse API 请求 Meaning Like 单词,并以 JSON 格式返回单词及其标签(名词、动词、形容词...)。

我希望如果应用程序成功获取这些单词,那么成功文本将位于名为“fetchStatus”的变量中。

之后,我希望“fetchStatus”的值将在 res.render 中传输到具有 UI 代码的 index.ejs,以便用户可以查看从 Datamuse 获取是否成功。

运行提取的函数称为“FetchData(req.body.wordInput)”。

问题在于 res.render 函数在 FetchData 函数之前运行,因此 fetchStatus 值为空字符串。

在函数 FetchData 中,我尝试返回字符串并将其传递给 res.render 但没有成功。

如果我将“fetchStatus”作为参数或全局变量,也会发生同样的情况。

app.js
============
//jshint esversion:6

var fetchStatus = "";

var vocabularyTags = {
syn: {name:"synonym", freq:0},
n: {name:"noun", freq:0},
v: {name:"verb", freq:0},
adj:{name:"adjective", freq:0},
adv:{name:"adverb", freq:0},
u:{name:"undetermined", freq:0},
prop: {name:"propery", freq:0}
};



const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");

var app = express();

// Setting ejs
app.set('view engine', 'ejs');

// Setting body-parser
app.use(bodyParser.urlencoded({ extended: true }));



app.get("/",function(req,res){
// res.sendFile(__dirname+"/index.html");
res.render("index", {fetchStatus:"", vocabularyTags:{}});


});

app.post("/",function(req,res){
// var fetchStatus = "";
var buttonPressed = req.body.submit;

if (buttonPressed === "fetch") {
FetchData(req.body.wordInput);
console.log("Fetch Status: "+fetchStatus);
res.render("index",{ fetchStatus:fetchStatus ,vocabularyTags:{} });
}
else if (buttonPressed === "show") {
//ShowData();
var vocabularyTagsResults = vocabularyTags;
res.render("index",{fetchStatus:"" ,vocabularyTags:vocabularyTagsResults});

// Clear Vocabulary Tags Frequencies
for (var key in vocabularyTags) {
vocabularyTags[key].freq = 0;
}



}

});



app.listen(3000,function(){
console.log("Server is running on port 3000");
});


function FetchData(wordInput) {
// var fetchStatus = "";
var options = {
url:"https://api.datamuse.com/words",
method:"GET",
qs: {
ml: wordInput
}
};

request(options,function(error,response,body){

if (error) {
fetchStatus = error;
}
else {
var dataMuseML = JSON.parse(body);
console.log(dataMuseML);

// Counting the related tags
dataMuseML.forEach(function(item){
var tags = item.tags;
tags.forEach(function(tag){
vocabularyTags[tag].freq++;
});
});
fetchStatus = "Fetch from Datamuse API has succeeded!";
}
});

// return fetchStatus;
}


views/index.ejs
================
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<title>Datamuse API</title>
</head>

<body>
<h1>Datamuse API</h1>

<form action="/" method="post">
<input type="text" name="wordInput" placeholder="Enter a word...">
<button type="submit" name="submit" value="fetch">Fetch</button>
<button type="submit" name="submit" value="show">Show</button>
</form>

<h3> <%= fetchStatus %> </h3>


<% for (var key in vocabularyTags) { %>
<p> <span><%= vocabularyTags[key].name %>:</span> <span> <%= vocabularyTags[key].freq %></span> </p>
<% } %>


</body>


</html>

预期结果是“fetchStatus”将有成功或错误文本,因此我可以将其传递给 res.render,这会将其放入 index.ejs 中。

最佳答案

你应该使用Promise来实现

function FetchData(wordInput) {
// var fetchStatus = "";
var options = {
url:"https://api.datamuse.com/words",
method:"GET",
qs: {
ml: wordInput
}
};

return new Promise((resolve, reject) => {
request(options,function(error,response,body){

if (error) {
reject(error);
}
else {
var dataMuseML = JSON.parse(body);
console.log(dataMuseML);

// Counting the related tags
dataMuseML.forEach(function(item){
var tags = item.tags;
tags.forEach(function(tag){
vocabularyTags[tag].freq++;
});
});
resolve("Fetch from Datamuse API has succeeded!");
}
});
});
// return fetchStatus;
}

然后你可以这样调用它:

app.post("/",function(req,res){
// var fetchStatus = "";
var buttonPressed = req.body.submit;

if (buttonPressed === "fetch") {
FetchData(req.body.wordInput).then(res => {
console.log("Fetch Status: "+res);
res.render("index",{ fetchStatus:res ,vocabularyTags:{} });
}).catch(err => {
console.log("Error: "+err);
res.render("index",{ fetchStatus:err ,vocabularyTags:{} });
})
}
// ...
}

如果您想将结果保留在全局中,您只需设置 fetchStatus,然后调用 resolvethen 即可,如下所示:

// ...
return new Promise((resolve, reject) => {
if (error) {
fetchStatus = error;
}
else {
// ...
fetchStatus = "Fetch from Datamuse API has succeeded!";
}
});
});
resolve(fetchStatus);
}

app.post("/",function(req,res){
if (buttonPressed === "fetch") {
FetchData(req.body.wordInput).then(res => {
// res or fetchStatus should be available here but it's better to use res
console.log("Fetch Status: "+res);
res.render("index",{ fetchStatus:res ,vocabularyTags:{} });
})
}
}

关于javascript - NodeJS - 如何使 res.render() 在函数之后运行而不是异步运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57749520/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com