Promise
Promise 是异步编程的一种解决方案, 可以解决传统 Ajax 回调函数嵌套问题。
案例:模拟使用ajax连续发起两次请求
第一次请求monster.json获取到monster的id
json
{
"id": 1,
"name": "黑山老妖"
}
第二次请求需要根据第一次获取到的id来获取monster的详细信息
json
{
"address": "阴曹地府-黑山",
"skill": "翻江倒海功",
"age": 800
}
传统的ajax方式:
javascript
//jquery 发出 ajax 的方式
$.ajax({
url: "data/monster.json",
success(resultData) { //如果请求成功了,回调处理函数 success
console.log("第 1 次 ajax 请求 monster 基本信息=", resultData);
//发出第二次 ajax 请求
$.ajax({
url: `data/monster_detail_${resultData.id}.json`,
success(resultData) {
console.log("第 2 次 ajax 请求 monster 详细信息=", resultData);
//$.ajax => callback hell
}, error(err) { //出错的回调函数
console.log("出现异常=", err);
}
})
}, error(err) {
console.log("出现异常=", err);
}
})
使用promise:
javascript
//1. 创建 Promise 对象
//2. 构造函数传入一个箭头函数
//3. (resolve, reject) 参数列表 resolve: 如果请求成功, 调用 resolve 函数
//4. 如果请求失败, 调用 reject 函数
//5. 箭头函数体, 仍然是通过 jquery 发出 ajax
let p = new Promise((resolve, reject) => {
//发出 ajax
$.ajax({
url: "data/monster.json",
success(resultData) { //成功后回调函数
console.log("promise1 结果 =", resultData);
resolve(resultData);
}, error(err) {
//console.log("promise1 请求异常=", err);
reject(err);
}
})
})
//这里我们可以继续编写请求成功后的业务
p.then((resultData) => {
//这里我们可以继续发出请求
//console.log("p.then 得到 resultData", resultData);
return new Promise((resolve, reject) => {
$.ajax({
url: `data/monster_detail_${resultData.id}.json`,
success(resultData) { //第 2 次 ajax 请求成功,回调函数
console.log("promise2 结果 =", resultData);
//继续进行下一次的请求
resolve(resultData);
}, error(err) { //第 2 次 ajax 请求失败,回调函数
//console.log("promise2 请求异常=", err);
reject(err);
}
})
})
}).then((resultData) => {
//可以在这继续发起请求
}).catch((err) => { //这里可以对多次 ajax 请求的异常进行处理
console.log("promise 异步请求异常=", err);
})
注意事项和使用细节:
- 如果返回的是 Promise 对象,可以继续执行.then()
- .then((data)=>{}) 的 data 数据是上一次正确执行后 resolve(data) 返回传入的
- 通过多级.then() 可以对异步请求分层次请求,实现代码重排,代码逻辑更加清晰合理
- 通过多级.then() 后面的 .catch((err) => {}) 可捕获发生异常,便于调试