Promise相关概念和用法简要回顾:
Promise语义理解为承诺,承诺一件事情,这件事情,要么成功,要么失败。
看不懂就对了,大多数技术上的东西都是只可意会不可言传,所以直接来看代码意会一下。
最基本的示例:
let promise = new Promise((resolve, reject) => {
let flag = true
if (flag) {
resolve('成功了')
} else {
reject('失败了')
}
})
promise.then(success => {
console.log(success)
}, fail => {
console.log(fail)
})
上边的代码平平无奇,写出了一股蛇精病的感觉。实际中当然没人这么用,Promise主要是来处理异步任务的。
Project中的异步任务没完成,异步中的resolve和reject便不会触发,then方法也不会触发。
异步任务完成后,根据实际结果,要么成功调用resolve,要么失败调用reject,然后才会触发then方法。
所以Promise很适合处理异步任务:
function ajax(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.responseType = 'json'
xhr.onload = function () {
if (this.status === 200) {
resolve(this.response)
} else {
reject(new Error(this.statusText))
}
}
xhr.send()
})
}
ajax('/api/foo.json').then(function (res) {
console.log(res)
}, function (error) {
console.log(error)
})
上面代码演示了:成功了就调用resolve方法,传递返回的数据;失败了就调用reject方法,传递错误的原因。最后用then方法中的两个函数接收。
虽然好像有点东西,但是对于需要重重嵌套的经典回调地狱问题时,Promise似乎没有解决:
ajax('/api/urls.json').then(function (urls) {
ajax(urls.users).then(function (users) {
ajax(urls.users).then(function (users) {
ajax(urls.users).then(function (users) {
ajax(urls.users).then(function (users) {
})
})
})
})
})
但其实这是Promise使用的最常见的误区,正确用法应该使用Promise的链式调用then,先看代码:
ajax('/api/users.json')
.then(function (value) {
return ajax('/api/urls2.json')
})
.then(function (value) {
return ajax('/api/urls3.json')
})
.then(function (value) {
return ajax('/api/urls4.json')
})
.then(function (value) {
return ajax('/api/urls5.json')
})
如上代码中的ajax请求会从上到下依次执行,而then方法中return的promise对象,会在下一个then方法中的回调函数中被接收。
看不懂没关系,下面代码更简洁:
// 定义ajax
function ajax(param) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (param) {
resolve(param)
} else {
reject(new Error('没有参数'))
}
}, 1000)
})
}
// 调用
ajax(1).then(res => {
console.log(res)
return ajax(res + 1)
}).then(res2 => {
console.log(res2)
return ajax(res2 + 1)
}).then(res3 => {
console.log(res3)
})
上面代码仿ajax,调用ajax函数,传一个参数,1秒后返回这个参数,如果不传参,就抛出一个错误。
如上调用ajax函数时,会每隔一秒打印一个数,打印的数分别为1、2、3,这个用来意会的最简单的代码就不言传了,自己意会吧。
内容输出来源:拉勾大前端高薪训练营,以上文章中的内容根据老师讲课的语音和代码,结合自己的理解编辑完成。