Я знаю, что этот вопрос задают очень часто, и за это меня могут проголосовать против. Но мне очень трудно понять, как я могу дождаться, пока функция обработает данные, прежде чем возвращать значение.
Я просмотрел много популярных постов (например, здесь), но не могу добиться того, чего хочу.
Вот мой код:
app.post("/video_url", function (req, res) {
videoProcessed = videoScraper(req.body.videoURL.videoURL);
res.send(videoProcessed);
});
Он не ждет, пока эта функция обработает данные:
function videoScraper(url) {
console.info("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.info(err);
});
}
Я пробовал использовать обратные вызовы, но это стало действительно беспорядочно, и я не знаю, нужно ли было поместить обещание (если оно есть) в свой код.
@ShubhamYerawar Да, но тогда я должен использовать обещание, не так ли?
@ Jérémy Вы уже используете обещание с rp. Он возвращает обещание (это видно из использования .then и .catch)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Добавьте await и async (если у вас есть узел 8+):
app.post("/video_url", async function (req, res) {
const videoProcessed = await videoScraper(req.body.videoURL.videoURL);
res.send(videoProcessed);
});
А в вашей функции videoScraper нужно вернуть rp! :
function videoScraper(url) {
console.info("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);
});
}
Это будет зависеть от исправной работы videoScrapper, я понятия не имею, что такое rp, поэтому не могу сказать.
Не забудьте обработать videoProcessed === undefined (случай ошибки) в первом фрагменте кода. Его также можно абстрагировать с помощью express-promise-router, который даже улавливает асинхронные ошибки ... Это будет дальше.
Не стесняйтесь читать об await и async, действительно замечательно писать асинхронный код так же, как и синхронный код.
вау, хорошо, вот так просто! Спасибо большое, это работает как шарм!
Используйте 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.info("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
}
}
если ваш узел <8, используйте обещания (модуль синяя птица)
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
})
});
Не используйте const для объявления переменной, если его значение не является постоянным, и обычно используйте let вместо var.
Вы можете попробовать следующее:
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
})
});
И измените функцию на что-то, как показано ниже, чтобы вернуть обещание из того же:
function videoScraper(url) {
console.info("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;
});
}
Вы можете использовать async / await для достижения своей цели