In order not to wrap blocks of code in a promise callback (to save one level of indentation), I sometime do the following:
function myFunction() {
// Create the promise object and get the "resolve" callback
let promiseResolve = null;
const promise = new Promise((resolve, reject) => {
promiseResolve = resolve;
});
// Then later in the code:
setTimeout(() => {
// Something slow
promiseResolve();
}, 1000);
// And at the end
return promise
}
It works but it feels a bit messy. Is there any proper pattern to do this in JavaScript?
Is there any proper pattern to do this in JavaScript?
Yes, the proper pattern is what you are apparently trying to avoid.
function myFunction(data) {
return new Promise((resolve, reject) => {
// put code in here that calls resolve() or reject()
someAsyncOperation(data, function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
}
For what you're showing, there's just really no reason to assign the resolve()
or reject()
handlers outside the scope of the executor function.
Here are some of the benefits to keeping your code inside the Promise executor:
.then()
and .catch()
require that. To program in Javascript, one has to be used to that and expect it. It is often required in order to access parent scoped variables too.util.promisify()
or Bluebird's Promise.promisifyAll()
. Then, my logic flow is entirely made out of promise-based operations and I'm never even faced with the type of code you show and any temptation to write code like that is gone too.Some references:
Why does the Promise constructor need an executor?
Deferred Anti-Pattern
The Revealing Constructor Pattern
What's the correct pattern for Promise.defer?
If you really find that you think you "need" a Deferred object, then I'd suggest you encapsulate that functionality in a new object and use that, rather than manually coding it each time you use it. In all my coding, I've only ever found that code was easier to write and cleaner with a Deferred object and that was a pretty unusual system of a low level queue managing a bunch of a different tasks.
There are several examples of simple, short pieces of code to implement a Deferred object. Here's one:
Why does the Promise constructor need an executor?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With