持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
论述
通过使用Peomise和阅读Promise源码后会发现,Promise本质也是使用回调函数去定义异步任务结束后所需要执行的操作,只是这里是通过then方法传递进去的,Promise将回调分为两种,一种是成功回调onFulfilled,一种是失败回调onRejected
fetch('/api')
.then(function onFulfilled(data) {
// 成功数据data
}, function onRejected(error) {
// 失败原因error
}
)
这时候就会想到既然还是回调函数,那么如果连续串联多个异步任务,这里就仍然会出回调函数嵌套的问题
如ajax连续请求几个接口,并且都依赖上个接口返回的数据时,可能你会这样写:
ajax('/api-1').then(res1 => {
ajax('/api-2', res1).then(res2 => {
ajax('/api-3', res2).then(res3 => {
...
})
})
})
这样promise代码仍然会形成回调地狱,promise也就没有任何的意义,并且还增加了复杂度,还不如使用传统的回调方式,因此这也是很多人初用promise时很常见的误区
正确做法
嵌套使用的方式是使用Promise最常见的错误,那么正确的做法是如何呢?
实际上是借助于Promise then方法链式调用的特点,尽可能保证异步任务的扁平化
特点:
var promise = ajax('/api-1')
var promise2 = promise.then(
function onFulfilled(data) {
// 成功数据data
}, function onRejected(error) {
// 失败原因error
}
)
console.log(promise2 === promise) // false
then方法会返回一个promise对象,并且该promise对象和原来的promise不是同一个对象(promise2 !== promise),所以它和传统的链式调用返回this是不同的,这点是尤其需要注意的
因此多个接口请求做法是:
ajax('/api-1')
.then(res1 => {
return ajax('/api-2', res1)
})
.then(res2 => {
return ajax('/api-3', res2)
})
.then(res3 => {
return ajax('/api-4', res3)
})
注意本文都是使用伪代码,方便于理解,自己也可实际动手操作实践
总结
- Promise对象的then方法会返回一个全新的Promise对象
- 后面的then方法是在为上一个then方法返回的Promise注册回调
- 前面then方法中回调函数的返回值会作为后面then方法回调的参数
- 如果回调中返回的是Promise对象,那么后面then方法的回调会等待它的结束
往期精彩文章
🌟js 柯里化艺术
🌟简述BFC是什么,以及在工作中的应用场景
🌟从浏览器输入网址到页面渲染中间发生了什么(通俗易懂)
🌟发布订阅/观察者模式-真正对比区别
🌟webpack 手写插件流程