• promise、async和await之执行顺序的那点事


    首先在控制台测试以下代码

    复制代码
    async function async1(){
        console.log('2: async1 start')
        await async2()
        console.log('6: async1 end')
    }
    async function async2(){
        console.log('3: async2')
    }
    console.log('1: script start')
    setTimeout(function(){
        console.log('8: setTimeout') 
    },0)  
    async1();
    new Promise(function(resolve){
        console.log('4: promise1')
        resolve();
    }).then(function(){
        console.log('7: promise2')
    })
    console.log('5: script end')
    复制代码

    果然,实践才是检验真理的唯一标准。运行的结果与原文说的不一样。

    小结一下理解的概念:

    1、如果在函数定义时,在function前面加上async ,那么在调用它以后,会返回一个 Promise 对象(还是阮一峰老师说的精辟),如上面的async1()。

    当执行async1时,一旦遇到其中的 await 就会先返回,等到触发的异步操作async2完成,再接着执行async1函数体内后面的语句。

    2、Promise是一个立即执行函数。如上面编号为2、3、4的都是立即输出,排在编号5之前。

    上述代码我在console中执行多次顺序不变。将setTimeout的延时时间由0改为3000也一样。

    如何让编号7的语句在最后执行呢?办法是将代码中的resolve()也用setTimeout()包起来,并设置延时为3000来查看效果。

    什么是Async/Await?       

     async搭配await是ES7提出的,它的实现是基于Promise。

    注意:await函数不能单独使用,而且async函数返回的是一个Promise对象,可以使用then函数添加回调函数。当函数执行的时候,一旦遇到await函数就会先返回一个Promise对象,等到异步操作完成,再去执行后面的语句。如果 await 后面的异步操作出错,那么等同于 async 函数返回的 Promise 对象被 reject!
    • async/await是写异步代码的新方式,以前的方法有回调函数和Promise。
    • async/await是基于Promise实现的,它不能用于普通的回调函数。
    • async/await与Promise一样,是非阻塞的。
    • async/await使得异步代码看起来像同步代码,这正是它的魔力所在。

    当然,如果不理解Promise的概念,可能对上面的内容还是不明白。

    所以,下面简单说一下Promise的概念

    Promise是异步编程的一种解决方案,我理解是为了解决js中的回调地狱问题,让代码更清晰。

    ES6规定,Promise对象是一个构造函数,用来生成Promise实例

    复制代码
    var promise = new Promise(function(resolve, reject) {
      // ... some code
    
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    复制代码

    Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。

    它的作用是为Promise实例添加状态改变时的回调函数。then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。

    new出来的Promise会保持一个pending状态,当异步操作完成(通常如访问网址获取数据),相应地调用resolve或reject;Promise的状态由pending相应变更为fulfilled [实现] 或rejected[被否决] ,并且

    1 当promise 状态发生改变,就会触发.then()里的相应函数处理后续步骤

    2 promise 状态一经改变,不会再变

    then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

    注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。

    要区分几个概念,第一,reject是用来抛出异常的,catch是用来处理异常的;第二:reject是Promise的方法,而then和catch是Promise实例的方法(Promise.prototype.then 和 Promise.prototype.catch)。

    catch只是一个语法糖而己 还是通过then 来处理的

    then的第二个参数和catch捕获错误信息的时候会就近原则,如果是promise内部报错,reject抛出错误后,then的第二个参数和catch方法都存在的情况下,只有then的第二个参数能捕获到,如果then的第二个参数不存在,则catch方法会捕获到。

    建议总是使用catch方法,而不使用then方法的第二个参数。理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。

    算了,感觉还是一头雾水。平时知道对new出来的promise对象连续调用then方法就好了,就像本文开头的代码或下面的代码

    复制代码
    new Promise(function(resolve, reject) {
    
      setTimeout(() => resolve(1), 1000);
    
    }).then(function(result) {
    
      alert(result); // 1
    
      return new Promise((resolve, reject) => { // (*)
        setTimeout(() => resolve(result * 2), 1000);
      });
    
    }).then(function(result) { // (**)
    
      alert(result); // 2
    
      return new Promise((resolve, reject) => {
        setTimeout(() => resolve(result * 2), 1000);
      });
    
    }).then(function(result) {
    
      alert(result); // 4
    
    });
    复制代码

    参考:https://segmentfault.com/a/1190000015057278

    https://www.jianshu.com/p/79c9e6c961cd

    https://blog.csdn.net/gogo_steven/article/details/103352762?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

    https://blog.csdn.net/ligen52/article/details/82187682?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

    https://blog.csdn.net/weixin_42470791/article/details/82560734

    https://www.cnblogs.com/pu369/p/12523361.html

  • 相关阅读:
    NFS(Network File System)即网络文件系统 (转)
    抓包神器 tcpdump 使用介绍 (转)
    sms短信网关对接
    spring 事务的传播级别和隔离级别
    持续集成是什么?
    理解Cookie和Session机制
    使用df -h命令查看磁盘空间使用率不算高,还有很多空余空间,但是创建文件或写入数据时一直报错磁盘写满
    删除文件后,磁盘空间没有释放的处理记录
    Springboot启动原理解析
    使用idea创建springboot项目
  • 原文地址:https://www.cnblogs.com/wyd168/p/13925053.html
Copyright © 2020-2023  润新知