1

ES6 native promises do not allow you to synchronously check if they're resolved/pending/failed or to extract their value. I sometimes need this functionality and thus I have to code it manually.

Is this considered an anti-pattern? Is this why this feature was left out of the standard?

This is a situation where I think this sort of feature comes in handy:

// the render method of a React component
// it will get triggered by other events other than the promise state change
render() {
  if (promise.resolved) {
    // render the result
  } else if (promise.rejected) {
    // render an error/reason
  } else {
    // render a loading message
  }
}
  • 1
    Could you give an example of what you needed this functionality for? – Ixrec Feb 7 '16 at 14:19
  • @Ixrec added example – adrianton3 Feb 7 '16 at 14:33
  • @adrianton3 Your entire problem is that you try to rely on a naturally asynchronous mechanism in order to perform a synchronous operation (render). Does render have to be synchronous? How React does it's data binding? How do you refresh a view? – plalx Feb 7 '16 at 16:54
1

The main problem I'm aware of with synchronous inspection is that it's completely unnecessary, unless your code relies on the promise resolving or rejecting within a certain number of ticks, which is exactly the sort of thing you should not rely on.

For instance, although I know nothing about React, I'm pretty sure your example could be changed into something like this:

this.text = "";

var promise = ...;
promise.then(function(result) {
    this.text = "Success: " + JSON.stringify(result);
}).catch(function(error) {
    this.text = "Error: " + JSON.stringify(error);
});

...

render() {
  // render the current value of this.text
}

You could even argue this version is better decoupled because now the render method has no idea that the value of this.text depends on that one specific promise. You could now easily make this.text depend on the results of several different promises chained together without causing a combinatorial explosion of synchronously inspecting if statements.

The only other argument for synchronous inspection which I'm aware of is that "it is known in certain code paths that a promise is guaranteed to be fulfilled at that point - it would then be extremely inconvenient to use .then to get at the promise's value as the callback is always called asynchronously." I would rather use .then() even in these cases, because a promise is not really guaranteed to be fulfilled until you're in its .then handler (or .spread handler or whatever). Assuming otherwise just creates an obvious way for my program to break in the future, no matter how airtight my argument might be today. If the handler being called on the next tick is a serious problem, then you're already depending on how many ticks certain operations do or don't take to resolve/reject, which is something you need to fix properly rather than work around.

  • In C#, inspecting this way is a synchronous call; it will block until the "promise" either completes or aborts. .then() probably makes more sense. – Robert Harvey Feb 7 '16 at 15:07
  • @RobertHarvey Aren't we talking about Javascript? – Ixrec Feb 7 '16 at 15:08
  • Yes, but I don't fully understand the promise mechanism in Javascript. The principles should be exactly the same, however. – Robert Harvey Feb 7 '16 at 15:09
  • @RobertHarvey In Javascript a promise library implementing "synchronous inspection" means there it has some getters that do not block or wait, but immediately tell you if the promise has been fulfilled or rejected yet (or neither). – Ixrec Feb 7 '16 at 15:11
  • @RobertHarvey We only have a single thread of execution in JS. Blocking APIs make very little sense so there is rarely a synchronous version like in C#, everything is usually async. – plalx Feb 7 '16 at 15:12
0

The purpose of a promise or future is to allow the promise to pursue calculations while you go and do something else ("in another thread"). Once you're done doing your other thing and come back to the promise to interrogate it for a value, the expectation is that you will then wait for the value (having completed "doing your other thing").

If you want to take action immediately when a promise has completed its task, I think you're better off having the "promise" notify you when it has completed. Use an event, in other words.

  • I'm not sure I understand how events are any more "immediate" than a promise resolution (unless your code relies on event handlers being called synchronously, which I thought was a bad thing). If anything, events seem less appropriate to me because in general an event is not guaranteed to ever fire, while a promise is always supposed to resolve or reject at some point. – Ixrec Feb 7 '16 at 14:53
  • @Ixrec: To put it another way, why would you ever poll an asynchronous mechanism? That's like parking your car twice. – Robert Harvey Feb 7 '16 at 15:04
  • That point I completely agree with. I guess I just failed to see that argument in your current answer. – Ixrec Feb 7 '16 at 15:07
0

I wouldn't call it an anti-pattern, I'd just call it silly (in most cases).

You are presumably using premises because you're dealing with some asynchronous work. That said, you should just assume that its status is pending until it says otherwise.

And with that said, you will presumably also have a section of code that deals with the promise events/callbacks. You'll set a default state (pending), and you'll subscribe to the success and failure events. And, if this if truly an asynchronous activity, code inspecting the promise synchronously is probably duplicative of code responding to the succeed/fail events. And if it's truly an asynchronous activity, that duplicative, asynchronous code will probably never even be executed.

  • This needs to be explained a little better to be a good answer. – Robert Harvey Feb 7 '16 at 15:17
  • @Robert sure! how's my edit? – svidgen Feb 7 '16 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.