发布请求等待功能

时间:2018-09-15 15:55:06

标签: javascript node.js asynchronous

我知道这个问题经常被问到,我对此可能会感到沮丧。但是我真的很难理解如何在返回值之前如何等待函数处理数据。

我浏览了许多热门帖子(例如here),但我无法实现自己想要的。

这是我的代码:

   app.post("/video_url", function (req, res) {
       videoProcessed = videoScraper(req.body.videoURL.videoURL);
       res.send(videoProcessed);
   });

它不等待此功能处理数据:

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

我尝试使用回调,但是它确实很混乱,而且我不知道是否将诺言(如果有的话)放在我的代码中。

3 个答案:

答案 0 :(得分:3)

添加等待和异步(如果您的节点为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.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);
    });
}

这取决于videoScrapper的工作正常,我不知道rp是什么,所以我不知道。

不要忘记在第一个代码段中处理videoProcessed === undefined(错误情况)。也可以使用express-promise-router来抽象它,甚至可以捕获异步错误...这还很远。

不要犹豫,在等待和异步时进行读取,以与同步代码相同的方式编写异步代码真的很棒。

答案 1 :(得分:1)

使用异步/等待

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

如果您的节点是<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
})
});

除非变量的值是常数,否则请勿使用const进行变量声明,并且通常使用let而非var

答案 2 :(得分:1)

您可以尝试以下操作:

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