SOURCE

var hooks={};
function regHook(hookName, hookFn) {
  if (!hooks[hookName]) hooks[hookName] = []
  hooks[hookName].push(hookFn)
}
//串行
// function callAsyncSeries(hookName, done, ...args) {
//   const fns = hooks[hookName]
//   let i = fns.length;
 
//   let next = done
//   while(i) {
//     let fn = fns[--i]
//     console.log(fn)
//     let _next = next
//     next = () => fn(...args, _next)
//    console.log(next)
//   }
//   next()
// }
 
// regHook('asyncSer', (a, b, done) => { setTimeout(() => { console.log('timout 1', a, b); done() }, 1000) })
// regHook('asyncSer', (a, b, done) => { setTimeout(() => { console.log('timout 2', a, b); done() }, 2000) })
// regHook('asyncSer', (a, b, done) => { setTimeout(() => { console.log('timout 3', a, b); done() }, 3000) })

// callAsyncSeries('asyncSer', () => { console.log('done') }, 'aa', 'bb')


// function callPromiseSeries(hookName, ...args) {
//   return new Promise(resolve => {
//     const fns = hooks[hookName]
//     let i = fns.length
//     let next = resolve
//     while(i) {
//       let fn = fns[--i]
//       let _next = next
//       next = () => fn(...args).then(_next)
//     }
//     next()
//   })
// }
 
// regHook('promiseSer', (a, b) => {
//   return new Promise(resolve => 
//     setTimeout(() => { console.log('promiseSer 1', a, b); resolve() }, 2000)
//   )
// })

// regHook('promiseSer', (a, b) => {
//   return new Promise(resolve => 
//     setTimeout(() => { console.log('promiseSer 2', a, b); resolve() }, 3000)
//   )
// })

// regHook('promiseSer', (a, b) => {
//   return new Promise(resolve => 
//     setTimeout(() => { console.log('promiseSer 3', a, b); resolve() }, 1000)
//   )
// })

// callPromiseSeries('promiseSer', 'aa', 'bb').then(() => { console.log('done') })


///并行
// function callAsyncParallel(hookName, done, ...args) {
//   const fns = hooks[hookName]
//   let count = fns.length
//   let _done = () => {
//     count--
//     if (count === 0) {
//       done()
//     }
//   }
//   fns.forEach(fn => fn(...args, _done))
// }

// // 限制并发数
// function callAsyncParallelN(hookName, done, N, ...args) {
//   const fns = hooks[hookName]
//   let count = fns.length
//   let cur = 0
//   let limit = N < fns.length ? N : fns.length
//   let _done = () => {
//     count--
//     if (count === 0) {
//       done()
//     } else if (cur < fns.length) {
//       fns[cur++](...args, _done)
//     }
//   }
//   for (; cur < limit; cur++) {
//     fns[cur](...args, _done)
//   }
// }
 
// regHook('asyncParallel', (a, b, done) => { setTimeout(() => { console.log('asyncParallel 1', a, b); done() }, 1000) })
// regHook('asyncParallel', (a, b, done) => { setTimeout(() => { console.log('asyncParallel 2', a, b); done() }, 1000) })
// regHook('asyncParallel', (a, b, done) => { setTimeout(() => { console.log('asyncParallel 3', a, b); done() }, 1000) })

// //callAsyncParallel('asyncParallel', () => { console.log('done') }, 'aa', 'bb')
// //callAsyncParallelN('asyncParallel', () => { console.log('done') }, 2, 'aa', 'bb')




function callPromiseParallel(hookName, ...args) {
  return new Promise(resolve => {
    const fns = hooks[hookName]
    let count = fns.length
    let _done = () => {
      count--
      if (count === 0) {
        resolve()
      }
    }
    fns.forEach(fn => fn(...args).then(_done))
  })
}

// 限制并发数
function callPromiseParallelN(hookName, N, ...args) {
  return new Promise(resolve => {
    const fns = hooks[hookName]
    let count = fns.length
    let cur = 0
    let limit = N < fns.length ? N : fns.length
    let _done = () => {
      count--
      if (count === 0) {
        resolve()
      } else {
        if (cur < fns.length) {
          fns[cur++](...args).then(_done)
        }
      }
    }
    for (; cur < limit; cur++) {
      fns[cur](...args).then(_done)
    }
  })
}
 
regHook('promiseParallel', (a, b) => {
  return new Promise(resolve => 
    setTimeout(() => { console.log('promiseParallel 1', a, b); resolve() }, 1000)
  )
})

regHook('promiseParallel', (a, b) => {
  return new Promise(resolve => 
    setTimeout(() => { console.log('promiseParallel 2', a, b); resolve() }, 1000)
  )
})

regHook('promiseParallel', (a, b) => {
  return new Promise(resolve => 
    setTimeout(() => { console.log('promiseParallel 3', a, b); resolve() }, 1000)
  )
})

callPromiseParallel('promiseParallel', 'aa', 'bb').then(() => { console.log('done') })
callPromiseParallelN('promiseParallel', 2, 'aa', 'bb').then(() => { console.log('done') })
console 命令行工具 X clear

                    
>
console