How to resolve or reject a Promise (native) in Javascript outside of your scope?

Asked

Viewed 201 times

3

Most of the implementations I see of Promises (promises) in frameworks Javascript treats the use of Promises in a way that it is possible to access the functions responsible for rejection and resolution in any scope.

For example, Angular:

var defer = $q();

setTimeout(function () {
    defer.resolve({status: true});
}, 5000);

defer.promise.then(function (data) {
    console.log(data.status);
});

Something similar is possible to do in jQuery.

However, when using the Promise Javascript native, I can’t visualize how I could do such an operation, unless the call was within the callback passed as argument.

To do in Javascript, I would have to do so, theoretically:

 var p = new Promise(function (reject, resolve) {
        setTimeout(() => p({status: true}, 5000);
  });

  p.then((data) => console.log(data.status));

My question is whether there is any way to do the same operation, using the Promise Javascript native, the same way I did in the first example. Because depending on the structure of the project, it could be horrible to have to be held hostage from encapsulating something inside a callback to have the functionality of Promise. And from what I’ve been doing on the Internet, it seems that Promise Javascript was meant to be used anyway. :\

Is there any way simple to circumvent this limitation of the implementation of Javascript promises?

Note: I tried using the call Promise.resolve(promise), but I didn’t get the desired effect.

  • @Wailacemaxters, you want some additional information in the reply? :-)

1 answer

2


You could do this kind of gambit:

const controls = {};
const promise = new Promise((resolve, reject) => {
  controls.resolve = resolve;
  controls.reject = reject;
});

promise.then((val) => {
  console.log('Fui resolvida. Valor de resolução:', val);
});

setTimeout(() => {
  controls.resolve(1);
}, 1000);

This type of code is possible since the executing function (first argument passed to the constructor Promise) is executed synchronously, which allows you to "remove" the functions resolve and reject from within the callback.

However, the above code can be considered a anti-pattern (so much so that I hid it by default) and therefore its use should be discouraged. By design, the Promises were designed to be solved only through functions (resolve and reject) passed to the executor. Thus, it is not really a "limitation", but rather a choice.

The builder of Promise behaves in this way for a reason called throw Safety. This means that if an exception is thrown from within the executor, the constructor itself Promise capture the error and immediately reject the Promise, being the bounce value of the error itself released. This is important as it keeps a predictable code. [Reference]

Therefore, when there is a need to resolve a "promise" from outside its executor, it is more worthwhile to use a deffered, that allows you to do this. A Promise Javascript was not made with this use-case in mind. jQuery, for example, implements the jQuery.Deferred. It is worth noting that Promises and deferreds, although they have similar functions, they are not the same thing.


It is worth noting that the method ("static") Promise.resolve is not used to solve a Promise, but yes create a new promise, which will be immediately resolved with the value passed as the first argument of Promise.resolve. There is also the method Promise.reject, who behaves in the same way to create an immediately rejected promise.

This is not the case, but if there was a method Promise.prototype.resolve, this yes would be used to solve existing bodies of Promise.

  • 2

    Why the negative? In fact, I invite the person who negatively or post another answer. :-)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.