递归调用异步函数

Calling async functions recursively

我需要一个异步方法,例如。 getWeather 永远调用,在上一次调用成功和下一次调用开始之间有一小段延迟。为此,我使用了递归函数。我担心这是否会导致性能下降。有没有更好的方法来做到这一点?

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();
  1. 不需要delayTwoSecs功能,可以使用Promise.delay功能

  2. 而不是 getWeather,您可以使用 bluebirdPromisify 所有函数并使用适当的函数,在这种情况下 getAsync , 直接.

所以,你的程序就变成了这样

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));
})();

这叫做Immediately Invoking Function Expression.

setInterval() 用于重复请求

您使用嵌套调用使它过于复杂。请改用 setInterval()。

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);