我制作了一个简单的应用程序,它的UI显示了一个Input Text和两个按钮:Fetch和Show。
通常的想法是在用户键入一个单词并单击“提取”后 该应用程序将从Datamuse API请求类似“含义”的单词,并以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。
答案 0 :(得分:1)
您应该为此使用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,然后像这样调用resolve
和then
:
// ...
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:{} });
})
}
}