Отправить запрос на ожидание функции

Я знаю, что этот вопрос задают очень часто, и за это меня могут проголосовать против. Но мне очень трудно понять, как я могу дождаться, пока функция обработает данные, прежде чем возвращать значение.

Я просмотрел много популярных постов (например, здесь), но не могу добиться того, чего хочу.

Вот мой код:

   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);
    });
}

Я пробовал использовать обратные вызовы, но это стало действительно беспорядочно, и я не знаю, нужно ли было поместить обещание (если оно есть) в свой код.

Вы можете использовать async / await для достижения своей цели

Shubham Yerawar 15.09.2018 17:58

@ShubhamYerawar Да, но тогда я должен использовать обещание, не так ли?

Jerlam 15.09.2018 18:00

@ Jérémy Вы уже используете обещание с rp. Он возвращает обещание (это видно из использования .then и .catch)

coyotte508 15.09.2018 18:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
54
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Добавьте 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, действительно замечательно писать асинхронный код так же, как и синхронный код.

вау, хорошо, вот так просто! Спасибо большое, это работает как шарм!

Jerlam 15.09.2018 18:08

Используйте 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;
        });
}

Другие вопросы по теме