首页 > nodejs如何让request变成同步执行?

nodejs如何让request变成同步执行?

for (var index = 0; index < data.length; index++) {
    var req = http.request(urlEntity, function(res) {
        var content = "";

        res.on("data", function(data) {
        content += data;
        });
        res.on('end', function() {
            // 获取到数据
            ......
        });

    });

    req.on("error", function(e) {
            if(e){
                  console.info(e);
                // 遇到异常
            }   
    });
}

//往下执行

以上那段代码我需要有多个请求都发送成功才继续往下执行,但是由于异步,导致请求还没有响应回来就已经往下执行,求助下各位大神要怎么弄才能?
我自己的想法就是在每一个request里面设置一个标识和一个监听器,当回来的个数和data.length一致时才触发事件往下执行,但是这里出现了问题,不知道为什么异常数加上请求成功数加起来没有等于data.length。


可以用node.js+async.js来完成。

如果你的需求是:遍历data的每一个元素, 并对每一个元素做http request, 每个request异步完成。当所有request全部完成后,返回response给用户。代码如下:

var content = "";
async.forEach(data, function(index, callback) { //The second argument (callback) is the "task callback" for a specific index
    http.request(urlEntity, function(res){
      res.on("data", function(data) {
        content += data;
      });
    }); // This way async knows which index in data have finished
}, function(err) {
    if (err) return next(err);
    //Respond the user about the content when they're all done.
    res.json({
        success: true,
        message: content
    });
});

如果你的需求是:遍历data的每一个元素, 并对每一个元素做http request, 每个request顺序完成。当所有request全部完成后,返回response给用户。代码如下:

var content = "";
async.forEachLimit(data, 1, function(index, callback) { //The second argument (callback) is the "task callback" for a specific index
    http.request(urlEntity, function(res){
      res.on("data", function(data) {
        content += data;
      });
    }); // This way async knows which index in data have finished
}, function(err) {
    if (err) return next(err);
    //Respond the user about the content when they're all done.
    res.json({
        success: true,
        message: content
    });
});

用队列

var req_funcs = [];
for (var index = 0; index < data.length; index++) {
    req_funcs.push(function(){
        return http.request(urlEntity, function(res) {
            var content = "";
            res.on("data", function(data) {
            content += data;
            });
            res.on('end', function() {
            });
        });
    });
}

var do_next = function(){
    var req_func = req_funcs.shift();
    if(req_func){
        var req = req_func();
        req.on("end",do_next);
    }else{
        //if all finished erer
    }
}
do_next();
 

这样的需求不仅仅在Nodejs里面会遇到在Client里面同样也有:第二个请求依赖于第一个请求的数据,那么顺序执行就成为了必然。

用递归解决就会陷入回调陷阱:一层嵌套一层的回调,代码阅读起来难度很高。

Promise

Promise首先是一种协议,jQuery为了Promise重写了它的大部分代码。它就是用来处理你的需求,顺序调用。

简单来说它的思想是:当一个方法执行完成之后,返回的是一个事先约定的对象,可以被下一个调用执行。这个讲我估计要开篇文章来写,这里推荐几篇文章阅读

http://www.html5rocks.com/zh/tutorials/es6/promises/
http://wiki.commonjs.org/wiki/Promises
http://www.infoq.com/cn/news/2011/09/js-promise

类似的文章好多,只是帮你开启一个思路,试试看Promise,你的代码风格都会发生变化


aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa


自带的官方好像没说有改成同步的方法,不过你完全可以不用自带的嘛!强大的npm已经有你想要的东西了啊:https://www.npmjs.org/package/httpsync

如果实在是想要用自带的写的话只能用递归来解决异步循环这个问题了。大概是以下这个样子的:

var data = [];
(function getdata(index) {
    if(index>=data.length) return true;

    var queryUrl = data[index];
    var req = http.request(urlEntity, function(res) {
        var content = "";

        res.on("data", function(data) {
            content += data;
        });
        res.on('end', function() {
            //do something u want!
            getdata(index+1);
        });

    });

    req.on("error", function(e) {
            if(e){
                  console.info(e);
            }   
    });
})(0)

当然是request-promise,

npm install request-promise

是request和promise衍生出来的包,以后写请求后端api的代码既可以实现同步,具体demo参看官方文档

【热门文章】
【热门文章】