阅读 171

浅析promise与async/await

一、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,因为它只会跳过异步代码。

文章分类
前端