const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const log = _ => console.log(_)
const flat = (arr, depth = 1) =>
arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flat(v, depth - 1) : v), [])
const subFlow = createFlow([() => delay(1000).then(() => log("c"))]);
createFlow([
() => log("a"),
() => log("b"),
subFlow,
[() => delay(1000).then(() => log("d")), () => log("e")],
]).run(() => {
console.log("done");
});
// 函数式
function createFlow(effects = []) {
return {
run: (cb) => effects.reduce((promise, cur) => {
if(Array.isArray(cur)) return promise.then(createFlow(cur).run)
else if(typeof cur.run === 'function') return promise.then(cur.run)
else return promise.then(cur)
},
Promise.resolve()).then(cb)
}
}
// 面向过程
function createFlow(effects = []) {
const middleware = flat(effects.map(item => item.middleware ? item.middleware : item), Infinity)
function dispatch (i) {
let fn = middleware[i]
if (i === middleware.length) fn = null
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn()).then(dispatch.bind(null, i + 1));
} catch (err) {
return Promise.reject(err)
}
}
return {
run: (cb) => {
return dispatch(0).then(cb)
},
middleware
}
}