Javascript: Horizontal Chaining Promises Without Multiple Then Calls
Solution 1:
As others have said there is no built in way to do this. The following code might be of interest though.
There is a concept known as 'lifting' whereby you transform a function into one that works on wrapped values. In this case promises. It would look something like this:
constlift = (fn) => (promise) => promise.then(fn);
There is also the idea of chaining together a list of functions, composing them with one another. Like this:
constchain = (...fns) => (value) => fns.reduce((result, fn) =>fn(result), value)
Together, these tools allow you to rewrite your code as:
chain(
lift(_=>++_),
lift(_=>_*=_),
lift(_=>alert(_))
)((async()=>1)())
Which alerts 4 as expected.
I'm also a little confused by your use of ++_
and _*=_
because they imply you wish to mutate the variable. Because of how your code is structured it would be a better display of intent to use _+1
and _*_
Solution 2:
Using Array.reduce()
, you can combine the series of functions into a promise chain using the following static function:
functionseries (initial, ...callbacks) {
return callbacks.reduce(
(chain, callback) => chain.then(callback),
Promise.resolve(initial)
)
}
series(1, _=>_+1, _=>_*_, alert)
For convenience, you could define this as Promise.series()
like this:
Object.defineProperty(Promise, 'series', {
configurable: true,
value: functionseries (initial, ...callbacks) { ... },
writable: true
})
Lastly, in ES2017, you could alternatively use async
/ await
to write it like this:
asyncfunctionseries(initial, ...callbacks) {
let value = await initial
for (const callback of callbacks) {
value = awaitcallback(value)
}
return value
}
series(1, _=>_+1, _=>_*_, alert)
Solution 3:
You can use rest parameter to pass N
functions to a function which return a Promise
to be called in sequence with the previous Promise
value set to parameter passed to the current function call until no elements remain in array using async/await
and repeated scheduling of the same procedure
consta = n => newPromise(resolve =>setTimeout(resolve, Math.floor(Math.random() * 1000), ++n));
constb = n => newPromise(resolve =>setTimeout(resolve, Math.floor(Math.random() * 1000), n * n));
const F = async(n, ...fns) => {
try {
while (fns.length) n = await fns.shift()(n);
alert(n);
} catch (err) {
throw err
}
return n
}
F(1, a, b)
.then(n =>console.log(n))
.catch(err =>console.error(err));
Solution 4:
Given that the code at Question is synchronous you can use the code at Question
((_) => (_++, _*=_, alert(_)) )(1)
Or use async/await
(async(_) => (_ = await _, _++, _ *= _, alert(_)))(Promise.resolve(1))
Post a Comment for "Javascript: Horizontal Chaining Promises Without Multiple Then Calls"