关于 JS Promise 一些错觉
我在编写一些库的时候,假设callback
是暴露给用户的接口,由外部传递进来,组件与用户交互多次触发这个回调,并且需要根据回调结果执行后续结果:
let ret = callback()
if(ret instanceof Promise){
ret.then(resp=>balabala(resp))
}else{
balabala(resp)
}
这是我长时间编写写强类型语言带来的影响,虽然可以运行,但是非常的啰嗦,使用Promise.resolve()
可以完成上面的逻辑:
Promise.resolve(callback()).then(resp=>balabala(resp))
如果callback
返回的是一个非Promise
对象,经过Promise.resolve
封装一次变成Promise
对象,如果已经是Promise
对象了,那么直接返回。
Promise.resolve(Promise.resolve(Promise.resolve(1))).then(v=>console.log(v))
// 运行结果:1
对于多个 Promise 需要等待全部完成,可以使用Promise.all()
。Promise.all()
接收一个可迭代对象,
并且等待其中的所有 Promise 完成才执行下一步的操作,其中只要有一个对象返回的结果是reject
,那么Promise.all()
也会返回reject
结果,这个过程是并行的,
前后任务不会相互阻塞。如果需要顺序运行,可以使用reduce
,下面代码会顺序执行每个任务,会在 4s 后输出结果:
const job1 = () => new Promise(resolve => setTimeout(resolve, 3000));
const job2 = () => new Promise(resolve => setTimeout(resolve, 1000));
[job1, job2]
.reduce((p, job) => p.then(job),Promise.resolve())
.then(()=>console.log("done"));
Promise 有三种状态,分别是 pending、fulfilled、rejected,对于单个内容一般根据状态就可以判断任务执行成功或是失败,
我刚刚接触使用 Promise 的时候,对于需要返回执行失败状态 Promise 的时候,大多数都是直接调用 Promise.reject() ,由于没有填写执行失败的内容,
导致在非常长的调用链执行失败的时候,不知道是哪里出错了。
所以对于需要返回 Promise.reject() 的地方,必须填写执行失败的原因,这个 reason 必须继承 Error,在必要的时候还需要 error wrap,以保证输出更加详细的错误信息。
Promise.reject(reason);