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();
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Cyril
  • 167
  • 1
  • 4
  • 11

2 Answers2

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.

Community
  • 1
  • 1
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
-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);
FactoryAidan
  • 2,484
  • 1
  • 13
  • 13
  • 3
    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.. – Cyril Mar 02 '15 at 07:29
  • 1
    Oh my. Why are you using a string in `setInterval()`? – JLRishe Mar 02 '15 at 07:29
  • @JSRishe have you ever tried to build a `setInterval()` command dynamically? That is how you do it. – FactoryAidan Mar 02 '15 at 07:54
  • 1
    @FactoryAidan: No it's not. I doubt this even works, as `getWeather` is not global in node.js. – Bergi Mar 03 '15 at 12:28