Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript NodeJS-如何使res.render()在函数之后而不是异步运行_Javascript_Node.js - Fatal编程技术网

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

Javascript NodeJS-如何使res.render()在函数之后而不是异步运行,javascript,node.js,Javascript,Node.js,我制作了一个简单的应用程序,它的UI显示一个输入文本和两个按钮:Fetch和Show 一般的想法是在用户键入一个单词并单击“Fetch”之后 该应用程序将从DatamuseAPI请求类似于单词的含义,并以JSON格式返回单词及其标记(名词、动词、形容词…) 我希望,如果应用程序成功获取这些单词,那么成功文本将位于名为“fetchStatus”的变量中 之后,我希望“fetchStatus”的值将在res.render中传输到具有UI代码的index.ejs,以便用户能够 查看从Datamuse获

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

一般的想法是在用户键入一个单词并单击“Fetch”之后 该应用程序将从DatamuseAPI请求类似于单词的含义,并以JSON格式返回单词及其标记(名词、动词、形容词…)

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

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

运行fetch的函数称为“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>
app.js
============
//jshint版本:6
var fetchStatus=“”;
var词汇标签={
syn:{name:“同义词”,频率:0},
n:{name:“名词”,频率:0},
v:{name:“动词”,频率:0},
形容词:{name:“形容词”,频率:0},
副词:{name:“副词”,频率:0},
u:{name:“待定”,频率:0},
道具:{name:“propery”,频率:0}
};
const express=要求(“express”);
const bodyParser=require(“body parser”);
常量请求=要求(“请求”);
var-app=express();
//设置ejs
应用程序集(“查看引擎”、“ejs”);
//设置主体解析器
use(bodyParser.urlencoded({extended:true}));
应用程序获取(“/”,函数(请求,恢复){
//res.sendFile(uu dirname+“/index.html”);
res.render(“索引”,{fetchStatus:,词汇标记:{});
});
应用程序post(“/”,功能(请求,回复){
//var fetchStatus=“”;
var buttonPressed=req.body.submit;
如果(按下按钮==“获取”){
获取数据(请求主体wordInput);
日志(“获取状态:+fetchStatus”);
res.render(“索引”{fetchStatus:fetchStatus,词汇标记:{}});
}
否则如果(按下按钮==“显示”){
//ShowData();
var vocabularyTagsResults=vocabularyTags;
res.render(“index”,{fetchStatus:,vocabularyTags:vocabularyTagsResults});
//清除词汇标签和频率
for(词汇标签中的var键){
词汇标签[key].freq=0;
}
}
});
app.listen(3000,函数(){
log(“服务器正在端口3000上运行”);
});
函数FetchData(wordInput){
//var fetchStatus=“”;
变量选项={
url:“https://api.datamuse.com/words",
方法:“获取”,
qs:{
ml:wordInput
}
};
请求(选项、功能(错误、响应、正文){
如果(错误){
fetchStatus=错误;
}
否则{
var dataMuseML=JSON.parse(body);
console.log(dataMuseML);
//计算相关标签
dataMuseML.forEach(函数(项){
var tags=item.tags;
tags.forEach(函数(tag){
词汇标签[tag].freq++;
});
});
fetchStatus=“从Datamuse API获取已成功!”;
}
});
//返回状态;
}
视图/index.ejs
================
DatamuseAPI
DatamuseAPI
取来
显示
:


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

为此,您应该使用
Promise

函数获取数据(wordInput){
//var fetchStatus=“”;
变量选项={
url:“https://api.datamuse.com/words",
方法:“获取”,
qs:{
ml:wordInput
}
};
返回新承诺((解决、拒绝)=>{
请求(选项、功能(错误、响应、正文){
如果(错误){
拒绝(错误);
}
否则{
var dataMuseML=JSON.parse(body);
console.log(dataMuseML);
//计算相关标签
dataMuseML.forEach(函数(项){
var tags=item.tags;
tags.forEach(函数(tag){
词汇标签[tag].freq++;
});
});
解析(“从Datamuse API获取已成功!”);
}
});
});
//返回状态;
}
然后你可以这样称呼它:

app.post(“/”,函数(req,res){
//var fetchStatus=“”;
var buttonPressed=req.body.submit;
如果(按下按钮==“获取”){
获取数据(req.body.wordInput)。然后(res=>{
日志(“获取状态:+res”);
res.render(“索引”{fetchStatus:res,词汇标记:{}});
}).catch(错误=>{
日志(“错误:+err”);
res.render(“index”,{fetchStatus:err,词汇标签:{}});
})
}
// ...
}
如果要将结果保存在全局中,只需设置fetchStatus,然后调用
resolve
,然后像这样调用

/。。。
返回新承诺((解决、拒绝)=>{
如果(错误){
fetchStatus=错误;
}
否则{
// ...
fetchStatus=“从Datamuse API获取已成功!”;
}
});
});
解决(获取状态);
}
应用程序post(“/”,功能(请求,回复){
如果(按下按钮==“获取”){
获取数据(req.body.wordInput)。然后(res=>{
//res或fetchStatus应该在这里可用,但最好使用res
日志(“获取状态:+res”);
res.render(“索引”{fetchStatus:res,词汇标记:{}});
})
}
}

非常感谢Mckael的可能副本。我真的很感激它,它工作得很好。根据您的解决方案,我将“then”中的“res”更改为:FetchData(req.body.wordInput)。然后(fetchStatus=>{console.log(“fetchStatus:+fetchStatus”);res。