使用promises的异步事件序列

时间:2014-08-06 17:33:10

标签: javascript

我是JavaScript的新手,并试图了解如何编写一些代码,这些代码根据先前生成的输入列表的内容对两个第三方API进行大量异步调用。

收集完所有数据后,我想创建一个图表。

我尝试过多种方式,但从我读过的内容来看,使用promises似乎是推荐的方式。我的大脑被扭曲,首先使用传统的异步模型然后试图理解承诺。

有人能指出我正确的方向吗?

var countries = [];
// countries ends up with 10-30 country names in previous code    
var total_population = 0;
for(var n=0; n<countries.length; ++n) {
    var country_data=new CountryData();
    // async function that fetches country data
    country_data.get(countries[n]);
    country_data.onDone = function() {
        var capital=this.capital;
        var city_data=new CityData();
        // async function that fetches city data
        city_data.get(capital);
        city_data.onDone = function() {
            total_population += this.population;
        }
    }
}
// make a chart with total_population for example.

2 个答案:

答案 0 :(得分:0)

我在这种情况下使用的一般模式是将我的所有承诺推送到一个数组中,然后设置一个promise动作来获取所有返回的值并执行我想要的(console.log是你的朋友,看看如何返回数据):

编辑:country_data.get必须返回一个promise对象才能生效。

var countries = ['US', 'CA', 'GB'];
var promises = [];
// countries ends up with 10-30 country names in previous code    
for(var n=0; n<countries.length; ++n) {
    var country_data=new CountryData();
    // async function that fetches country data and returns a promise
    promises.push(country_data.get(countries[n]));
}

//This will fire only once all async calls complete
Promise.all(promises).then(function(data) {
    console.log(data);
    //do stuff with data from all calls
}

警告:我通常使用jquery,它使用稍微不同的语法,并且jsfiddle已关闭,所以这还没有经过全面测试。

答案 1 :(得分:0)

假设CountryData#get和CityData#get返回承诺,解析请求的国家/城市数据,我就是这样处理的:

var total_population = 0;

var promise = Promise.all(countries.map(function(country) {
  return new CountryData().get(country)
    .then(function(countryData) {
      return new CityData().get(countryData.capital);
    })
    .then(function(cityData) {
      total_population += cityData.population;
    });
}));

编辑:更改解决方案以返回单个承诺