本文不对Promise的做过深的解析,只对基础的使用方法,然后会记录一些promise的使用技巧,可以巧妙的解决异步的常见问题。
在过去一直理解的是解决了一直异步回调的坑,但是用了npm async之后感觉异步回调其实稍微习惯一下其实还是蛮友好的。
其实相对于async(npm那个)使用promise的好处主要在于:
1. 可以 进行 then和catch对错误和流程进行控制。把错误控制和流程控制分离,写的时候可以更加专注流程。
2. 语义上和同步代码逻辑类似,理解程度更加容易
1. 基础语法
Promise对象
Promise状态
pending 初始化
fulfilled 执行成功
rejected 执行失败
快速生成Promise对象
上述相当于一下的代码
Promise.all和race方法
all就是全部promise对象全部执行成功或者失败,race就是有一个执行成功或者失败。返回值和reject及resolve一样是一个promise对象
2. Promise进阶
promise很优秀的一点其实在于他可以pending,我们只记录他,并不去执行
所以就可以有如下的写法
循环存储
Promise.all(data.map((itemInfo => { let item = new Model(itemInfo); return item.save(); })));
迭代
let sequentiallyStore = function (model, data) { let current = 0; const len = data.length; const Model = mongoose.model(model); function save() { current++; if (current < len) { const item = new Model(data[current]); return item.save().then(save); } else { return Promise.resolve(); } } save(); data.reduce((pre, cur) => { return pre.then() }, new Promise()) };
3. Promise的使用
方便流程控制
每一个Promise都有then和catch方法,resolve会进入then中一直往下执行,reject会直接调到catch中进行错误处理,所以我们书写一个promise流程时,只要遇到错误,就只管reject就行,然后在最后进行错误处理即可,不需要担心如何去把错误返回给下一步。在这一点是和express的设计思想一致,所以流程我我们尽量少的去加工和操作错误,可以统一在最后一步处理。好处在于
1. 更加专注业务
2. 错误集中处理
方便业务重构
封装promise的函数可以类似于一个个的插槽,所有异步处理统一用promise可以更加方便的抽离业务,把业务分解成一个个功能性的插槽,然后再重组实现项目的其他业务,在封装工具函数,分离通用业务时会更加清晰明了,方便进行项目的迭代。
提高代码可读性
异步任务通过then进行后续处理,就会类似于同步的业务逻辑,可读性很高。
为了提升代码的可读性和方便代码的控制,尽量去封装成各种功能的promise在项目里进行重组。不要一直then的往下写。