2

I need to have an async method eg. getWeather called forever with a small delay between the success of previous call and beginning of the next call. I have used a recursive function for the purpose. I am concerned if this can cause a performance hit. Are there any better ways to do this?

var request = require('request');
var Promise = require('bluebird');

var delayTwoSecs = function() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve();
        }, 2000);
    });
};

var getWeather = function() {
    return new Promise(function(resolve, reject) {
        request({
            method: 'GET',
            uri: 'http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139'
        }, function(error, response, body) {
            if (error) {
                reject(error);
            } else {
                resolve(body)
            }
        });
    });
};

var loopFetching = function() {
    getWeather()
        .then(function(response) {
            console.log(response);
            return delayTwoSecs();
        }).then(function(response) {
            loopFetching();
        });
};

loopFetching();

2 Answers 2

3
  1. You don't need the delayTwoSecs function, you can use the Promise.delay function.

  2. Instead of getWeather, you can use the bluebird to Promisify all the functions and use the proper function, in this case getAsync, directly.

So, your program becomes like this

var Promise = require('bluebird');
var request = Promise.promisifyAll(require('request'));
var url = 'http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139';

(function loopFetching() {
    request.getAsync(url)
         // We get the first element from the response array with `.get(0)`
        .get(0)
         // and the `body` property with `.get("body")`
        .get("body")
        .then(console.log.bind(console))
        .delay(2000)
        .then(loopFetching)
        .catch(console.err.bind(console));
})();

This is called Immediately Invoking Function Expression.

Sign up to request clarification or add additional context in comments.

3 Comments

This is functionally and peformance-wise same as the code in the question right?
@Cyril I don't see any reason to be concerned about performance in either approach.
You can change .then(function(response){ response[0].body } with .get(0).get("body").then(function(body){ ... Also - might as well chain promises.
-1

setInterval() for recurring requests

You're over-complicating it with nested calls. Use setInterval() instead.

var request = require('request');
var Promise = require('bluebird');

var getWeather = function() {
    return new Promise(function(resolve, reject) {
        request({
            method: 'GET',
            uri: 'http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139'
        }, function(error, response, body) {
            if (error) {
                reject(error);
            } else {
                resolve(body)
            }
        });
    });
};

var my_interval = setInterval("getWeather()",2000);

4 Comments

I needed the next call to be initiated only if the previous call was successful. And I also need to make sure the there is a constant delay in the interim. setInterval won't take care of the above two cases I guess..
Oh my. Why are you using a string in setInterval()?
@JSRishe have you ever tried to build a setInterval() command dynamically? That is how you do it.
@FactoryAidan: No it's not. I doubt this even works, as getWeather is not global in node.js.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.