一、promise
1、概念:
promise是异步编程的解决方案,它有三种状态:pending(等待态)、fulfiled(成功态)、rejected(失败态)。
2、作用
1、回调地狱:代码较难维护
2、用来解决异步的问题
3、方法
promise是一个构造函数,方法有then、catch、all、reject、resolve;
//项目中封装的截图的方法,html2canvas
const catchPicture = function (obj) {
let imgUri = "";
let scale = 1;
let dom = document.querySelector(obj.dom);
return new Promise(function (success, fail) {
html2canvas(document.querySelector(obj.dom), {
scale: scale,
width: dom.offsetWidth,
height: dom.offsetHeight
}).then(function (canvas) {
imgUri = canvas.toDataURL("image/png", 0);
if (imgUri) {
success(imgUri);
} else {
fail("error");
}
});
});
};
then和catch方法
then有两个参数,resolve\reject,第一个对应resolve的回调,第二个对应reject的回调:
//这里catch的作用和then的第二个参数一致,另外他还可以在第一个参数执行异常时,不会卡js的执行
p.then((data)=>{
console.log('resolved',data)
},(err)=>{
console.log('rejected',err)
})
.catch((err)=>{
console.log('rejected',err)
})
all方法
all方法接收一个数组参数,里面的值最终都会返回promise对象,并行执行异步操作,并且在所有异步操作执行完后才执行回调。
当整个数组的全部promise成功时才会返回成功,当数组中的promise有一个出现失败时就返回失败 (失败的原因是第一个失败promise的结果)。
let Promise1 = new Promise(function(resolve, reject){})
let Promise2 = new Promise(function(resolve, reject){})
let Promise3 = new Promise(function(resolve, reject){})
let p = Promise.all([Promise1, Promise2, Promise3])
p.then(funciton(){
// 三个都成功则成功
}, function(){
// 只要有失败,则失败
})
race方法
race含有竞速的意思,将多个Promise放在一个数组中,数组中有一个promise最先得到结果,不管是" 完成(resolved)"还是" 失败(resolved)" , 那么这个 .race 方法就会返回这个结果。
Promise.race([promise1, promise2]).then(success, fail)
// promise1和promise2只要有一个成功就会调用success;
// promise1和promise2只要有一个失败就会调用fail;
// 总结: 谁第一个成功或失败,就认为是race的成功或失败。
二、async/await
1、概念:
async函数,是generator函数的语法糖,它建立在promise上,并且和现有的基于promise的api兼容。
async
1、async声明一个异步函数(async function event(){...});
2、自动将常规函数转成promise,返回值也是一个promise对象;
3、只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数
await
1、await-暂停异步的功能执行(var result = await someAsyncCall(););
2、放置在promise调用之前,await强制其他代码等待,直到promise完成并返回结果;
3、只能在async函数内部使用;
三、async/await和Promise的比较
1、先来看下简单的代码例子比较,假设getName返回值是Promise:
// promise
const makeRequest = ()=>{
getName().then(data => {
console.log(data)
return 'done'
})
}
makeRequest()
// async/await
const makeRequest = async ()=>{
// 等到getName()的promise成功resolve之后再执行
console.log(await getName());
return 'done'
}
2、async/await优势
1、代码读起来更加同步,promise虽然摆脱了回调地狱,但是then的链式调用可读性相对差些;
2、async/await几乎是同步的写法,非常优雅;
3、错误处理比较友好,async/await可以用成熟的try/catch,可以指向错误所在的函数。promise需要使用自身的catch方法;
4、调试友好,promise调试很差,两个原因:不能在返回表达式的箭头函数中设置断点,如果你在.then代码块中设置断点,使用Step Over快捷键,调试器不会跳到下一个.then,因为它只会跳过异步代码。