javascript - making API calls blocking with nodejs - Stack Overflow

I'm not sure if this is the right way to do this, but I am looking to make 10 API requests in a fo

I'm not sure if this is the right way to do this, but I am looking to make 10 API requests in a for loop, and I want every API request to be blocking. That is, to wait until I receive the response without going to a callback and then iterating over the foor loop again. Here is the foor loop

for (var i=0; i< out.items.length; i++) {
    var object = makediffbotAPIcall(out.items[i]);
    console.log(object);
}

The request function is the following

function makediffbotAPIcall(item, array) {
    var url_to_send_diffbot = "string of url here";

    request(url_to_send_diffbot, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var article_object = JSON.parse(body)       
            var object = {"Title": article_object.title, "Url":article_object.url};
        }

    });

    return object;
}

The problem with this code is that object doesn't return in time for the foor loop to make use of it. I tried putting a setTimeout at the end of the makediffbotAPIcall function, but that didn't work either. Any suggestions are much appreciated. Thanks!

I'm not sure if this is the right way to do this, but I am looking to make 10 API requests in a for loop, and I want every API request to be blocking. That is, to wait until I receive the response without going to a callback and then iterating over the foor loop again. Here is the foor loop

for (var i=0; i< out.items.length; i++) {
    var object = makediffbotAPIcall(out.items[i]);
    console.log(object);
}

The request function is the following

function makediffbotAPIcall(item, array) {
    var url_to_send_diffbot = "string of url here";

    request(url_to_send_diffbot, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var article_object = JSON.parse(body)       
            var object = {"Title": article_object.title, "Url":article_object.url};
        }

    });

    return object;
}

The problem with this code is that object doesn't return in time for the foor loop to make use of it. I tried putting a setTimeout at the end of the makediffbotAPIcall function, but that didn't work either. Any suggestions are much appreciated. Thanks!

Share Improve this question edited Jan 28, 2016 at 22:19 DifferentPseudonym 1,0241 gold badge12 silver badges28 bronze badges asked Feb 8, 2013 at 21:37 Nosayr YassinNosayr Yassin 4191 gold badge6 silver badges15 bronze badges 2
  • possible duplicate of How can I make this call to request in nodejs synchronous? – JohnnyHK Commented Feb 8, 2013 at 21:46
  • The magic word you're looking for is asynchronous semaphore en.wikipedia/wiki/Asynchronous_semaphore – Benjamin Gruenbaum Commented Feb 8, 2013 at 22:13
Add a ment  | 

4 Answers 4

Reset to default 4

There is a very good node.js library "async" for managing the control flow in a asynchronous environment. For this specific issuse https://github./caolan/async#forEach series version and there is a little modification in makediffbotAPIcall makes thing work exactly as you are looking for so here is the solution

async.forEachSeries(out.items,function(item,callback){
makediffbotAPIcall(item,out.items,function(object){
//here you will get either object or null
callback();
}),function(err){
// this will be called when all array items will get processed
})

function makediffbotAPIcall(item, array, callback) {

var url_to_send_diffbot = "string of url here"


request(url_to_send_diffbot, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var article_object = JSON.parse(body)       
        return callback({"Title": article_object.title, "Url":article_object.url})

    }
    else
        return callback(null);
})
}

I am not sure about the second parameter to makediffbotAPIcall I assume that you want to pass plete array so, I simply pass the whole array if that's not the case you can modify it as you want.

Let me know if you have any questions.

Async.js is a good place to start, there are others like these - https://github./joyent/node/wiki/modules#wiki-async-flow

Note, however, that 'blocking' code is not a good idea in node/js. It is a single threaded event driven language. You don't want to block code, because then your server, for example, will stop reacting to request. Because of the above, most of the asnyc patterns will ask you to provide a callback function , sometimes called 'next' that you need to call at the end of each function , so the next function in line will be called.

You need forEachSeries(arr, iterator, callback) from async.js library.

What it does is that it iterates over the arr in a non-overlapping sequential manner. Perfect for repetitive tasks to be executed in sequence. Callback is called once all iterations finish. Best part is it does it cleanly without callback hassles.

You should try other functions from async.js. It is a great library and very handy.

I find it's often useful when dealing with async issues in JS to move and name all anonymous functions, temporarily, to explicitly show when they are being passed and when they are being invoked.

function makediffbotAPIcall(item, array) {

    var url_to_send_diffbot = "string of url here"

    var receiveResponse = function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var article_object = JSON.parse(body);   
            var object = {"Title": article_object.title, "Url":article_object.url};
        }
    }

    request(url_to_send_diffbot, receiveResponse);
    return object;
}

So there are a few problems here. 1st, even if your request was synchronous (which would be a terrible thing, for poor old single threaded javascript), this would not work because you use var object inside receiveResponse, so that variable will not be available outside that function!

For this particular problem, the simplest solution is to call console.log(object) inside receiveResponse. Assuming you've actually simplified some code that does something more plicated, there are a variety of patterns available. Is it important that each request happens sequentially after the previous one, or is it ok to run in parallel and log separately (possibly out of order)? Basically, you'll want to either add a callback param to makediffbotAPIcall and invoke that function with object inside responseReceived, or return a Promise object, which is probably overkill unless you're already using a framework/library that provides them, or you really need lots of support for parallel and/or sequential operations.

I re-read you're question and it looks like you want blocking behaviour, here's a pure JS solution (no lib required =P) using recursion:

var i=0;
var callNext = function(object){
    if(i<out.items.length) {
        makediffbotAPIcall(out.items[i], callNext);
    }
    console.log(object);
    i++;
}

callNect("nothing to log for first obj");

function makediffbotAPIcall(item, array, callback) {

    var url_to_send_diffbot = "string of url here"

    var receiveResponse = function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var article_object = JSON.parse(body);   
            var object = {"Title": article_object.title, "Url":article_object.url};
            callback(object);
        }
    }

    request(url_to_send_diffbot, receiveResponse);
}

This could do with some tidying (the base case for recursion is handled awkwardly) but you don't always need a library ;)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745255413a4618923.html

相关推荐

  • javascript - making API calls blocking with nodejs - Stack Overflow

    I'm not sure if this is the right way to do this, but I am looking to make 10 API requests in a fo

    5小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信