New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promise.deferred()? #80
Comments
The reasoning behind not adding deferreds is that they are usually are an anti-pattern and, even worse, an extra concept to learn. They’ve proven troublesome in user-space, and the promise constructor has proven to be a great fix. The only reason the spec uses it so much is because creating closures in ECMASpeak is a pain, so we encapsulate that in a single operation. This in turn causes us to have to manually re-capture exceptions and forward them to |
I should really change the rantish and hostile tone in that article :D |
I totally share the sentiment of that article, but the bad practice still happens with the promise constructor. It just looks like this: function someFunction() {
return new Promise(function (resolve, reject) {
otherPromise.then(function (value) {
resolve(doSomethingWithTheValue(value));
], reject);
});
} |
@juandopazo or function someFunction() {
return new Promise(function (resolve) {
resolve(otherPromise.then(SometingWithTheVlaue));
});
} or with something like foo: Promise.method(function(){
return otherPromise.then(somethingWithTheValue);
}); Additionally, the Promise constructor approach catches exceptions and propagates them as one would expect. |
This is one of the stronger arguments against deferreds, in practice. |
That´s a good point. I guess sharing |
@domenic ya. Additionally, it appears that modeling the promise as the thing that is the potential future value results in much more understandable and maintainable code. Using a deferred seems to almost always spiral away from this. Nearly each time I see a deferred used, it is being used as a lock/semaphore and in practice this seems to result in very hard to digest patterns. |
Same here. I haven't found it hard to digest in the cases I ran into, but it's definitely not a good idea. |
Hi Stefan, could you give an example of using a deferred as a On Mon, Dec 2, 2013 at 7:57 AM, Stefan Penner notifications@github.comwrote:
Text by me above is hereby placed in the public domain Cheers, |
@erights I recently saw something like this: function SomeConstruct() {
var deferred = Promise.deferred();
this._deferred = deferred;
this.ready = deferred.promise;
}
SomeConstruct.prototype.doSomething = function () {
var self = this;
return this.someThingElse().then(function () {
self._deferred.resolve();
//...
});
};
var foo = new SomeConstruct();
foo.ready.then(...); |
@petkaantonov Hi, is this still considered as an anti-pattern to use deferreds as observers? var pending = {};
pending._promise = new Promise(function(resolve, reject){
pending._resolve = resolve;
});
pending.ready = function() {
pending._resolve(true);
}
pending.onReady = function(fn) {
pending._promise.then(fn);
}
pending.onReady(function() {
console.log('YOLO PATTERN!')
});
setTimeout(pending.ready, 200); Or is this only taste? How would you implement this otherwise in a nice manner? Thanks. |
@vvo why the extra layer for var pending = {}; // not sure what pending is.
pending.ready = new Promise(function(resolve){ setTimeout(resolve, 200); });
pending.ready.then(fn); // instead of `.onReady(fn) |
Was for the example, did not wanted to expose the underlying implementation (promise). So that, you want to change the implementation with say, array of callbacks, you can. Also I do not want the API consumer to use the _promise. |
Why would you not want to expose the fact it's a promise? A promise is generic. You can always do: |
@benjamingr it's only encapsulation, we are missing the point of the deferred anti-pattern here :) was just an example. |
I'm trying to understand your use case here - why do you need a deferred in the first place? The deferred anti pattern is about creating an excess deferred for wrapping an existing promise in another promise where |
I am using Promise and deferred pattern only to not have to implement myself an array of callbacks + ready flag condition + foreach callback. I do not wrap an existing promise. The way the example is written is only to be able to hide the implementation of my observer object. Like a lot of objects say in Node.js core are "hiding" (_prefixing) some properties. This is a completely different subject. I only wanted to show how deferred can be used to solve some problems and that it's not always an antipattern. |
If you're not wrapping another promise than you are not doing the deferred anti-pattern, deferred is not an anti-pattern itself.. While I don't think your use is particularly good - it׳s not related to what Petka's article discusses. |
So you would implement this using an array of callbacks right? |
So, not to stir up an old discussion but deno is using Deferreds and when I raised the issue of throw safety it looks like they are using them like locks. @stefanpenner asked about using promises as semaphores and @erights asked for an example but I don't actually see a conclusion of what's the "better" way to do it. Would appreciate some guidance/ideas/thoughts. |
The only use case I can think of the current API doesn't address is handing out the capability to resolve/reject a promise. We can of course do:
...but it's a bit awkward. Should we add
Promise.deferred
exposingGetDeferred
?The text was updated successfully, but these errors were encountered: