Thanks in advance everyone.
I am using ES6 native promises for the first time (in the past, I've used Q or Angular's $q service). I have a problem that would be easily solved by using a deferred, and was surprised to discover that ES6 promises don't use them.
I was further surprised to discover a large number of people on blogs referring to the usage of deferred as an anti-pattern. Even after reading a few blogs decrying their use, I still don't really understand why - their examples were largely places where I never would have used a deferred to begin with so maybe I'm missing something (and wouldn't mind an explanation of why they are bad as an aside). But in the interests of remaining within the confines of best practices, I'm trying to figure out how to solve something without pulling in a library that supports them, and I'm stuck.
I am using the OpenLayers library to create a map in my React/Redux application. OpenLayers requires a DOM element to place the map on when the map object is created. Therefore I cannot instantiate the OpenLayers map until the component has mounted. That's fine, there's a lifecycle hook for that with componentDidMount.
Where I run into a problem is that I need to expose that map object to other classes and those classes have code that needs to wait to run until the map has been created.
With a deferred, I could handle this fairly simply as shown below:
const deferred = Q.defer();
const Foo = React.createClass({
componentDidMount() {
const map = new ol.Map(...);
deferred.resolve(map);
}
...
}
export getMap => deferred.promise
But with ES6 promises, I'm stuck.
I can't instantiate the promise outside of the componentDidMount class because it will fire immediately.
If I instantiate a promise (or use Promise.resolve since my code is synchronous) within the scope of the componentDidMount function, the promise is out of scope for the getMap function.
If I declare but do not instantiate the promise object outside of scope of componentDidMount, getMap would return undefined until componentDidMount executes, defeating the point of having a promise in the first place.
As a final thought, I am not putting the map in the Redux state because OpenLayers maps are highly mutable and do their own thing, it would break the Redux commitment to immutability if I put the map in there... so I've abandoned Redux solutions. Throwing some kind of boolean on the Redux state like "mapAvailable" feels like a hack. I could probably make that work but it would introduce a host of secondary problems.
So what am I missing? Am I in a corner case where deferreds are really the right answer or am I just not seeing the obvious?
Again, thank you for your time.