Below the Radar Below the Radar - 1 year ago 127
Javascript Question

Promise.all() - Do something after multiple event listeners are triggered

I am using a cartographic API that implement a

object. There is an event on the layer that is fired when the layer's
finished loading. This process is asynchronous.

I want to use Promise to handle the moment when features of each map's layers are loaded. However sometimes layer's features are already loaded before I have added the listener and sometimes not.

I am trying to use
like below, but I am not sure if its the best way to achieve what I am trying to do.

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

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

layers.forEach(function(layer) {
if (layer.features.length > 0) {
//features are already loaded
} 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) {

ajm ajm
Answer Source

That seems like a perfectly valid use of Promise.all.

One thing to note: your forEach loop will need to return promises in the addEventListener case so Promise.all can operate on them.

Using map() might be a little bit easier for you as you'll have a nice Array to pass right into Promise.all.

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

That will give you an array of promises for layers that have yet to load and promises that resolve immediately for those already loaded.