Skip to content

JavaScript中Promise在同步代码中的两种执行方式 #36

Open
@gnipbao

Description

@gnipbao

1.同步串行执行多个Promise

  1. reduce实现
// async tasks with return promise
let runPromiseSequence = (asyncTasks) => {
        let reducer = (acc, curr) => acc.then(() => curr()); 
	return asyncTasks.reduce(reducer, Promise.resolve()); 
};
runPromiseSequence.then((ret)=>{
    // todo
})
  1. reduce 和 async实现
// promises
let runPromiseSequence = (tasks) => {
	return tasks.reduce(async (curr, next) => {
		await curr;
		return next();
	}, Promise.resolve());
};
runPromiseSequence.then((ret)=>{
    // todo
})

解析

reduce里的第一个函数相当于一个reducer可以传递4个参数:

  • acc累计器
  • cur当前值
  • idx 当前索引
  • arr 数组

第二个参数可以理解为acc的初始值,在reduce执行时候先会赋值acc初始值initValue也就是一个Promise.resolve(),curr赋值为当前tasks的第一个值也就是数组中第一个异步函数,由于tasks是一个promise异步任务函数 ,这里使用Promise.resolve()来触发执行,这时候会触发acc.then()然后执行curr也就是第一个异步函数执行并继续返回一个promise赋值给acc,curr取下一个异步函数这样就能实现串行执行每个task。
第二种async只不过是将reducer函数使用aysnc函数来实现本质上是类似的只是代码看起来简单很多。
注意reducer中第一个参数其实是一个执行后的结果这里是Promise而非函数。

2.同步并行执行多个Promise

并行比较简单使用Promise.all原生api既可以实现。

3. 简单测试

const createPromise = (time, id) => () =>
  new Promise(solve =>
    setTimeout(() => {
      console.log(`p=>${id}`);
      solve();
    }, time)
  );
runPromiseSequence([
  createPromise(3000, 1),
  createPromise(2000, 2),
  createPromise(1000, 3)
])

可以在控制台通过打印顺序可以看出每个任务串行执行。

Promise.all([
  createPromise(3000, 1)(),
  createPromise(2000, 2)(),
  createPromise(1000, 3)()
]).then((ret)=>console.log);

并行执行

4. 参考

https://github.com/sindresorhus/promise-fun

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions