0

I have a function for send GET http request with request package. This works good.

//file1.js
var request = require('request');
methods.testcall = function(callback){
    request(url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            callback(body)
        }
        if(!error && response.statusCode == 429){ // Rate limit.., try again 1s
            setTimeout(this(callback), 1000);
        }

    })
};

In the next file, i call this function two times. I think the 2 request can run in one time. So when the request is arrive then i call the callback function. In the log i see the result. But, where u see my comment, there i want to wait for ALL testcall(), because i want to be sure in all data arrived to my server.

//file2.js
test.methods.testcall(function(response){
    console.log(response)
});

test.methods.testcall(function(response){
    console.log(response)
});

// Here, i want to wait for all testcall function.
// When all testcall function sent response 
// Im ready to do smtng :)

How can i wait this two method there? Thanks so much!

vihkat
  • 895
  • 3
  • 13
  • 28
  • "*`setTimeout(this(callback), 1000)`*" - what? – Bergi Aug 23 '16 at 19:38
  • Oh, Im newbie in JS. Maybe `this()` is fine? not tested the 429 error yet – vihkat Aug 23 '16 at 19:40
  • 1
    You can create global variable and set its value to 0. After callback event is fired, you increase that variable. If value if 2, then you can be sure all of your callbacks are finished and you can call the rest of your code. –  Aug 23 '16 at 19:42
  • Yes i thinking about this. And where i want to stop the code there i write a while without body. Its do not eat the processor? – vihkat Aug 23 '16 at 19:47
  • `var responseNumber = 0; test.methods.testcall(function(response){ responseNumber += 1; checkResponse(responseNumber) }); test.methods.testcall(function(response){ responseNumber += 1; checkResponse(responseNumber) }); ... function checkResponse(responseNumb) { if(responseNumb == 2){ console.log("done"); } }` Its works good! Thanks, good idea! – vihkat Aug 23 '16 at 19:52
  • Please write an answer, i want to accept your idea! Thanks again! – vihkat Aug 23 '16 at 19:53
  • 1
    You could use a promise library like [`q`](https://www.npmjs.com/package/q) to run the requests asynchronously – mzmm56 Aug 23 '16 at 19:54

3 Answers3

1

This isn't tested, I think it would work for you though, it's using q

var request = require('request');
var Q = require('q');

methods.testcall = function (url) {
  return request(url, function (error, response, body) {
    // 
  });
};

Q.allSettled([
  method.testcall('http://'),
  method.testcall('http://')
]).done(function (results) {
  results.forEach(function (result) {
    //
  });
});
mzmm56
  • 1,264
  • 1
  • 14
  • 21
  • Its really nice, i like it, but something not work good :( . The foreach runs before the request end. – vihkat Aug 23 '16 at 20:11
  • @vihkat hm, sorry about that, have to run out, maybe try with just `return request(url)`? hope you figure something out! – mzmm56 Aug 23 '16 at 20:18
0

You can nest the testcall calls:

test.methods.testcall(function(response1) {
    test.methods.testcall(function(response2) {
        doSomething(response1, response2)
    }) 
})

The callback to the inner invocation of testcall will not be executed until that request is complete, giving you access to both responses.

This approach can be hard to follow, especially if you have even more calls to make. You would have to continue nesting them (also known as callback hell)

To simplify the process, you can also use libraries such as async.js Or a Promise library, such as Bluebird.js

For concurrent requests, check out the detailed approaches from this question: How can I wait for set of asynchronous callback functions?

Community
  • 1
  • 1
Ian
  • 480
  • 5
  • 8
  • 1
    But here, the second request starts when the first finished. – vihkat Aug 23 '16 at 19:43
  • I want to run all request in one time, becuse i want to call about ~20 api request – vihkat Aug 23 '16 at 19:44
  • Sorry! Didn't realize you wanted them to run concurrently. Linked you to another similar SO question that provides various approaches. – Ian Aug 23 '16 at 20:00
0

Now its works, good

methods.test = function (callback){


    request(url...., function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log("done");
            callback(body)
        }else if(!error && response.statusCode == 429){ // Rate limit
            console.log("rateLimit");
            setTimeout(function(){
                methods.test(callback)
            },1000);
        }else if(!error && response.statusCode == 403){ // Forbidden
            console.log("Forbidden");
            setTimeout(function(){
                methods.test(callback)
            },1000);
        }


    })
};



var responseNumber = 0;

test.methods.test(function(response){
    responseNumber += 1;
    checkResponse(responseNumber)
});

test.methods.test(function(response){
    responseNumber += 1;
    checkResponse(responseNumber)

});



function checkResponse(responseNumb)
{
    if(responseNumb == 2){
        console.log("done");

    }
}
vihkat
  • 895
  • 3
  • 13
  • 28