Promise.all() - 在触发多个事件侦听器后执行某些操作

时间:2016-03-21 12:59:25

标签: javascript events asynchronous promise

我正在使用实现layer对象的制图API。当图层features完成加载时,图层上会发生一个事件。这个过程是异步的。

我想使用Promise来处理加载每个地图图层的特征的时刻。但是,有时在添加侦听器之前已经加载了图层的功能,有时候没有。

我正在尝试使用下面的Promise.all(),但我不确定它是否是实现我想要做的最佳方式。

var layers = [layer1, layer2, layer3];
var promises = [];

Promise.all(promises).then(function() {
    //here am I sure that all layers features are loaded?
    doSomething();
});

layers.forEach(function(layer) {
   if (layer.features.length > 0) {
      //features are already loaded 
      onFeaturesLoaded();
   } else {
      //features not loaded yet, a one time event listener is added 
      layer.addOneTimeEventListener(layer.EVENTS.FEATURES_LOADED, onFeaturesLoaded, layer);
   }
});

function onFeaturesLoaded() {
   return new Promise(function(resolve) {
       resolve();
   });
};

2 个答案:

答案 0 :(得分:2)

这似乎是Promise.all的完全有效使用。

有一点需要注意:您的forEach循环需要在addEventListener案例中返回承诺,以便Promise.all可以对其进行操作。

使用map()对您来说可能会更容易,因为您将有一个很好的数组传递到Promise.all

Promise.all(layers.map(function(layer){ 
    if(layer.features.length === 0){
        return new Promise(function(resolve, reject){
            layer.addEventListener(layer.EVENTS.FEATURES_LOADED, function(){ resolve(); }, layer);
        });
    }
    else{
        return new Promise(function(resolve, reject){ resolve(); });
    }
})
.then(function(){ 
    // Everything is loaded at this point.
});

这将为您提供一系列承诺,用于尚未加载的图层,并承诺立即解决已加载的图层。

答案 1 :(得分:1)

根据@ ajm的解决方案稍作修改和DRYer答案:

Promise.all(layers.map(function(layer){ 
    return new Promise(function(resolve, reject) {
        if(layer.features.length === 0) {
            layer.addOneTimeEventListener(layer.EVENTS.FEATURES_LOADED, function(){ resolve(); }, layer);
        } else {
            resolve();
        }
    });
}))
.then(function(){ 
    // Everything is loaded at this point.
});