Promise与Async Await详解
不管是使用还是面试,Promise都是一整个重点,下面来总结下Promise和Async Await。
先看下常见的异步操作:
事件监听:
document.getElementById('#start').addEventListener('click', start, false);
function start() {
// 响应事件,进行相应的操作
}
// jquery on 监听
$('#start').on('click', start)
回调
// 比较常见的有ajax
$.ajax('http://www.wyunfei.com/', {
success (res) {
// 这里可以监听res返回的数据做回调逻辑的处理
}
})
// 或者在页面加载完毕后回调
$(function() {
// 页面结构加载完成,做回调逻辑处理
})
(1)Promise
Promise主要用于异步任务,将异步的任务队列化,他主要解决了异步操作不小心就会进入回调地狱模式中,他将回调地狱的嵌套模式改为了链式调用模式,利于代码可读性和维护性。
promise代码:
new Promise(
function (resolve, reject) {
// 一段耗时的异步操作
resolve('成功') // 数据处理完成
// reject('失败') // 数据处理出错
}
).then(
(res) => {console.log(res)}, // 成功
(err) => {console.log(err)} // 失败
)
(1)resolve作用是将promise对象状态从未完成变为成功,异步操作成功时调用,并将异步操作的结果作为参数传出去。
reject的作用是,将promise的状态从未完成变为失败,在异步操作失败时调用,并将异步操作报的错作为参数传递出去
(2)promise有三个状态:pending初始状态,fulfilled操作成功,rejected操作失败状态
(3)promise的状态一经改变,只有两种可能:从pending变为fulfilled,从pending变为rejected,并且,转态一旦改变,就凝固了,不会在变。
promise.then()
new Promise(resolve => {
setTimeout(() => {
resolve('hello')
}, 2000)
}).then(val => {
console.log(val) // 参数val = 'hello'
return new Promise(resolve => {
setTimeout(() => {
resolve('world')
}, 2000)
})
}).then(val => {
console.log(val) // 参数val = 'world'
})
(1).then()返回一个新的promise实例,这是实现链式调用的关键
(2)接收两个函数作为参数,分别代表fulfilled和rejected
(3)promise状态改变时,.then根据最终状态,选择特定的状态响应函数执行
(4).then()返回其他值,那么会立即执行下一级的.then()
错误处理
promise会自动捕获内部异常,并交给rejected响应函数处理
(1)reject(‘错误信息’).then(() => {}, () => {错误处理逻辑}),catch返回得也是一个promise对象
(2)throw new Error(‘错误信息’).catch( () => {错误处理逻辑})
promise.all()批量执行
Promise.all([p1, p2, p3])用于将多个promise实例,包装成一个新的Promise实例,返回的实例就是普通的promise
它接收一个数组作为参数
数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变
当所有的子Promise都完成,该Promise完成,返回值是全部值得数组
有任何一个失败,该Promise失败,返回值是第一个失败的子Promise结果
//切菜
function cutUp(){
console.log('开始切菜。');
var p = new Promise(function(resolve, reject){ //做一些异步操作
setTimeout(function(){
console.log('切菜完毕!');
resolve('切好的菜');
}, 1000);
});
return p;
}
//烧水
function boil(){
console.log('开始烧水。');
var p = new Promise(function(resolve, reject){ //做一些异步操作
setTimeout(function(){
console.log('烧水完毕!');
resolve('烧好的水');
}, 1000);
});
return p;
}
Promise.all([cutUp(), boil()])
.then((result) => {
console.log('准备工作完毕');
console.log(result);
})
Promise.race()
Promise.race() 类似于Promise.all() ,区别在于它有任意一个完成就算完成
(2)Async Await
async函数是Generator的语法糖,阮一峰老师详细讲解过了,链接阮一峰async
Async Await是对promise的优化,Async Await是一种更优雅的写法,将异步的代码优化为了同步的写法,我们看一个异步操作,并看下promise和Async Await的实现。
/**
* 传入参数 n,表示这个函数执行的时间(毫秒)
* 执行的结果是 n + 200,这个值将用于下一步骤
*/
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n + 200), n);
});
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(n) {
console.log(`step2 with ${n}`);
return takeLongTime(n);
}
function step3(n) {
console.log(`step3 with ${n}`);
return takeLongTime(n);
}
使用promise
function doIt() {
console.time("doIt");
const time1 = 300;
step1(time1)
.then(time2 => step2(time2))
.then(time3 => step3(time3))
.then(result => {
console.log(`result is ${result}`);
console.timeEnd("doIt");
});
}
doIt();
// c:\var\test>node --harmony_async_await
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 1507.251ms
使用async await
async function doIt() {
console.time("doIt");
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time2);
const result = await step3(time3);
console.log(`result is ${result}`);
console.timeEnd("doIt");
}
doIt();
本文地址:https://blog.csdn.net/weixin_44517681/article/details/107893454