Promise
1.处理异步操作,避免回调地狱(大量的回调函数调用),是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
2.ES6的Promise是一个构造函数, 用来生成Promise实例, Promise实例是异步操作管理者。
3.Promise代表了未来某个将要发生的事件(通常是一个异步操作) 有了Promise对象, 可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(俗称’回调地狱’)。
4.Promise为了取代回调函数。
Promise一共有3个状态, 和执行顺序
- pending: 初始化状态
- fulfilled: 成功状态
- rejected: 失败状态
new Promise时, 回调函数马上执行, 而异步任务则是通过回调
let promiseObj = new Promise((resolve, reject) => {
// pending(初始化状态)
console.log('promise刚开始'); // 同步执行
setTimeout(function () {
// 启动异步任务
console.log('异步任务操作成功');
resolve('请求成功了'); // pending----> fulfilled(成功状态)
// reject('请求超时了'); // pending----->rejected (失败状态)
}, 2000)
});
promiseObj.then(data => {
console.log(data);
}).catch(err => {
console.error(err);
});
console.log('主线程执行-------');
回调地狱案例
在第一个接口请求成功后,继续请求第二个接口…
$.ajax({
url: "接口地址",
type: "POST",
dataType: "json",
success(res) {
$.ajax({
url: `接口地址`,
data: {
firstId: res['data'][2]['first_id']
},
type: "POST",
dataType: "json",
success(res2) {
$.ajax({
url: `接口地址`,
data: {
secondId: res2['data'][0]['second_id']
},
type: "POST",
dataType: "json",
success(res3) {
$.ajax({
url: `接口地址`,
data: {
thiredId: res3['data'][0]['thired_id']
},
type: "POST",
dataType: "json",
success(result) {
console.log(result);
}
})
}
})
}
})
}
})
改写成Promise配合下面async+await改写成同步的
async function(){
const res = await myAjax("/one")
const res2 = await myAjax("/two");
const result = await myAjax("/three");
}
// 注意; (myAjax内使用Promise没有贴出来)
使用
1.创建Promise对象, 返回结果
let promise = new Promise((resolve, reject) => {
// 生成Promise对象, 包含异步操作
setTimeout(()=>{
// 异步操作, 返回结果
resolve("成功返回");
// reject("报错返回");
}, 2000);
});
2.调用then方法, 接收异步–成功结果
promise.then(data => {
// 使用then方法接收 异步成功的结果
console.log(data);
})
3.调用catch方法, 接收异步–报错结果
promise.then(data => {
// 使用then方法接收 异步成功的结果
console.log(data);
}).catch(err => {
// 使用catch方法接收 异步报错的结果
console.error(err);
})
4.链式调用then方法, then里return会返回一个Promise对象
promise.then(data => {
return "链式调用";
}).then(res => {
console.log(res);
})
使用promise async await 封装ajax请求
function getNews(url) {
return new Promise((resolve, reject) => {
// 创建一个promise对象, 并返回
$.ajax({
url,
type: 'GET',
success: data => resolve(data),
error: error => reject(error)
})
})
}
getNews('https://cnodejs.org/api/v1/topics').then((news) => {
document.body.innerHTML = news['data'].reduce((str, obj) => {
return str += `<h4>${
obj['title']}</h4>`
}, "");
})
Promise.all
作用: 可以用于把多个Promise对象合并成 一个大的promise对象使用
案例: 获取3个一级分类下所属的二级分类数据
扫描二维码关注公众号,回复:
12666441 查看本文章

url: 地址 one two three
// 如果每次调用一个Promise对象, 用then每个来分别接收ajax回来的数据
// 注意: 顺序不对, 而且谁先回来不一定, 3个回调, 没法等待同一时间返回
// 引出, Promise.all() 会根据数组的顺序, 把返回的Promise.all的数据按照数组的顺序组织返回
Promise.all([one, two, three]).then(res => {
console.log(res);
}).catch(err => {
console.error(err);
})
// 注意, 这一组promise对象, 有一个触发了失败reject, 那么then不会执行