[英]Post request to wait a function
I know the question is asked really often, and I might get downvoted for that. 我知道这个问题经常被问到,我对此可能会感到失望。 But I really struggle to understand how I can wait for a function to process data before returning a value. 但是我真的很难理解如何在返回值之前如何等待函数处理数据。
I had a look on many popular posts (such as here ), but I cannot achieve what I want. 我浏览了许多受欢迎的帖子(例如here ),但无法实现自己想要的功能。
Here is my code: 这是我的代码:
app.post("/video_url", function (req, res) {
videoProcessed = videoScraper(req.body.videoURL.videoURL);
res.send(videoProcessed);
});
It does not wait for this function to process the data: 它不等待此函数处理数据:
function videoScraper(url) {
console.log("URL to Scraper: " + url);
const options = {
uri: `${url}`,
transform: function(body) {
return cheerio.load(body);
}
};
var videoProcessed;
rp(options)
.then(($) => {
videoProcessed = $("body").find("iframe").attr("src");
return videoProcessed;
})
.catch((err) => {
console.log(err);
});
}
I tried using callbacks but it gets really messy, and I don't know were to put the promise (if any) in my code. 我尝试使用回调,但是它确实很混乱,而且我不知道是否要在代码中放入promise(如果有)。
Add await and async (if you have node 8+): 添加等待和异步(如果您的节点为8+):
app.post("/video_url", async function (req, res) {
const videoProcessed = await videoScraper(req.body.videoURL.videoURL);
res.send(videoProcessed);
});
And in your videoScraper
function, you need to return rp
! 在videoScraper
函数中,您需要返回rp
! : :
function videoScraper(url) {
console.log("URL to Scraper: " + url);
const options = {
uri: `${url}`,
transform: function(body) {
return cheerio.load(body);
}
};
return rp(options)
.then($ => $("body").find("iframe").attr("src"))
.catch((err) => {
console.error(err);
});
}
That would depend on the videoScrapper
working fine, I've no idea what rp
is so I can't tell. 那将取决于videoScrapper
工作正常,我不知道rp
是什么,所以我无法分辨。
Don't forget to handle videoProcessed === undefined
(error case) in the first code snippet. 不要忘记在第一个代码片段中处理videoProcessed === undefined
(错误情况)。 It can also be abstracted using express-promise-router
that will even catch async errors... That's further down the road. 还可以使用express-promise-router
对其进行抽象,该express-promise-router
甚至会捕获异步错误...进一步的发展。
Don't hesitate to read up on await & async, it's really wonderful to write asynchronous code in the same manner as synchronous code. 不要犹豫,在等待和异步上进行读取,以与同步代码相同的方式编写异步代码真的很棒。
Use async/await 使用异步/等待
app.post("/video_url", async (req, res)=> {
try{
let videoProcessed = await videoScraper(req.body.videoURL.videoURL);
res.send(videoProcessed);
}
catch(ex){
// handle the exception
}
});
const videoScraper = async fuction(url) {
console.log("URL to Scraper: " + url);
let options = {
uri: `${url}`,
transform: function(body) {
return cheerio.load(body);
}
};
try{
let temp = await rp(options);
let videoProcessed = $("body").find("iframe").attr("src");// you can return it directly
return videoProcessed;
}
catch(ex){
// handle the exception
}
}
if you your node is < 8 then use promises ( bluebird module) 如果您的节点小于8,则使用promises( bluebird模块)
const bluebird = require('bluebird');
function videoScraper(url){
return new bluebird(function(resolve,reject){
let options = {
uri: `${url}`,
transform: function(body) {
return cheerio.load(body);
}
};
rp(options)
.then(($)=>{
resolve($("body").find("iframe").attr("src"));
})
.catch(err=>{
return err;
})
})
}
app.post("/video_url", (req, res)=> {
videoScraper(req.body.videoURL.videoURL)
.then(result=>{
res.send(result)
})
.catch(err=>{
// handle the error
})
});
Do not use const
for variable declaration unless its value is constant, and usually use let
instead of var
除非其值是常量,否则不要将const
用于变量声明,并且通常使用let
而不是var
You can try the following: 您可以尝试以下方法:
app.post("/video_url", function (req, res) {
videoScraper(req.body.videoURL.videoURL)
.then(videoProcessed => {
res.send(videoProcessed);
})
.catch(err => {
// render proper response with error message
})
});
And change the function to something as below, so as to return a promise from the same: 并将函数更改为以下内容,以从中返回promise:
function videoScraper(url) {
console.log("URL to Scraper: " + url);
const options = {
uri: `${url}`,
transform: function(body) {
return cheerio.load(body);
}
};
return rp(options)
.then(($) => {
videoProcessed = $("body").find("iframe").attr("src");
return videoProcessed;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.