Hello friends!
In this post, I decided to share with you one of the uses of the Array.prototype.reduce
a method, namely, using the method to consistently fulfill promises
.
In one of the works (AnimationJS, m4q), I needed to perform sequentially some (total number is unknown) number of animations. Each animation is a Promise
.
Animation definition
function animate(args){
return new Promise(function(){
...
})
}
Chain definition. Each argument for chain
is a plain object, who describe animation.
chain([{...}, {...}, ...])
async/await
The first thing that came to mind was to solve the problem using async/await:
async function chain(arr) {
for(let i = 0; i < arr.length; i ++) {
const a = arr[i];
a.loop = false;
await animate(a);
}
}
This works fine, but was not suitable for my m4q library written for Metro 4 on ECMAScript 5.1 due to lack of async/await support.
for Promise, I use polyfill
Finding a solution made it possible to use the reduce
method.
function chain(arr, loop = false){
const reducer = function(acc, item){
return acc.then(function(){
return animate(item)
});
}
arr.reduce(reducer, Promise.resolve());
}
How to reduce
works? The reduce()
method reduces the array to a single value. The reduce()
method executes a provided function for each value of the array (from left-to-right). The return value of the function is stored in an accumulator
(result/total). For initial value, I use empty resolve
. In next, on all iteration reducer execute Peromise
and call a next animation in resolver. Since the resolver is executed after the end of the promise, we get sequential animations when each next animation is executed only when the previous one is completed.
Now I can execute chain
of animations:
var ball = document.querySelector(".ball");
chain([
{
el: ball,
draw: {
top: [h - ball.clientHeight]
},
dur: 2000,
ease: "easeOutBounce"
},
{
el: ball,
draw: {
left: [w - ball.clientWidth]
},
dur: 2000,
ease: "easeOutBounce"
},
{
el: ball,
draw: {
top: 0
},
dur: 2000,
ease: "easeOutBounce"
},
{
el: ball,
draw: {
left: 0
},
dur: 2000,
ease: "easeOutBounce"
}
]);
Top comments (0)