Promise.series
and Promise.waterfall
with vanilla es Promise
/thenable
$ npm i promise.extra
import {
series,
waterfall,
reduce,
factory
} from 'promise.extra'
series([1, 2, 3], (prev, v) => Promise.resolve(v))
.then(values => {
console.log(values) // [1, 2, 3]
})
waterfall([1, 2, 3], 0, (prev, v) => Promise.resolve(prev + v))
.then(result => {
console.log(result) // 6
})
// The reducer could even returns non-promise values
waterfall(
[1, 2, 3],
0,
(prev, v, i) => i > 0
? prev + v
: Promise.resolve(prev + v)
)
.then(result => {
console.log(result) // 6
})
reduce([v1, v2, v3], reducer, initValue)
- tasks
Array<Task>
an array of tasks- Task
any
each of the tasks could be anything.
- Task
- reducer
?ReducerFunction
the reducer which will process eachtask
and returns either aPromise
or any value.
Always returns a Promise
.
function ReducerFunction (
prev: any,
task: Task,
index: number,
tasks
): Promise | any
- prev The result value of the last task which processed by the
reducer
. If the return value of the last reducer is anPromise
,prev
will be the value inside the promise. - task The current task.
- index The index of task
- tasks Just the
tasks
argument of functionseries
The default value of reducer
is:
(prev, currentValue) => currentValue
currentValue
is one of the Task
s, and each Task
could be a Promise
or a normal JavaScript variable or object.
If you want each of the Task
s to be a factory function that returns a Promise
or normal values, and execute each value inside the reducer, just define the reducer as:
function reducer (prev, factory) {
// If `series` is invoked by `series.call(this, ...args)`,
// reducer could share the `this` object.
return factory.call(this, prev)
}
- tasks
Array<PromiseFactory>
- PromiseFactory
Function(x): Promise
a factory function which receives a parameter and returns aPromise
- PromiseFactory
- initValue
any | undefined
optional initial value which will be passed into the first factory function. - reducer
Always returns Promise
.
- tasks
- reducer
Function(prev, factory, currentIndex, tasks): Promise
The reducer function - initValue
any | undefined
if no initial value is supplied,undefined
will be used.
Always returns Promise
Each of the methods is similar to the behavior of Array.prototype.<method>
.
- promise
Promise|PromiseLike
Creates the new reduce
, series
, waterfall
with the Promise
which can be bluebird
, promise-faker
or something.
import Promise from 'promise-faker'
const {
series
} = factory(Promise)
series(tasks)
const nickName = 'Steve'
// Suppose there are two async functions to check the nickName
series(
[checkNickNameSyntax, remoteCheckUnique],
(prev, factory) => factory(nickName)
)
function lessThan10 (notThrow) {
if (this.number < 10) {
this.number ++
return true
}
if (notThrow) {
return false
}
return Promise.reject('larger than 10')
}
series.call({number: 10}, [lessThan10, lessThan10])
// Reject
series.call({number: 1}, [lessThan10, lessThan10])
// Promise.resolve<true>
series.call({number: 10},
[lessThan10, lessThan10],
function (prev, factory) {
// 1. Be careful that you should use `factory.call` here
// to pass the `this` object to `factory`
// 2. use the parameter `notThrow`
return factory.call(this, true)
}
)
// Promise.resolve<false>
promise.extra
no longer supports node < 6 since 4.0.0
. For old node versions, require('promise.extra/legacy')
MIT