异步编程(async与await原理)

js中的异步编程

为什么要异步编程?

  • js是单线程的,如果一个任务很耗时,会阻塞后面的任务执行
  • 看MDN中的例子:https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Asynchronous/Concepts

就前面提到的种种原因(比如,和阻塞相关)很多网页API特性使用异步代码,特别是从外部的设备上获取资源,例如,请求API获取数据,发送请求获取图片,从网络获取文件,访问数据库等

  • 一个加载图片的例子:(取代的方法就是,代码必须等到 response 返回才能继续往下执行)

  • var response = fetch('myImage.png');
    var blob = response.blob();// 这段代码可能会报错,因为它在执行的时候不确定图片是否已经下载过来了
    
  • 处理文件的例子




Promise解决回调函数带来的回调地狱问题(嵌套过深)


协程



如何使用Generator函数


await 后面的表达式


原理


await转化例子1

async2() 为一个普通表达式,没有返回Promise,所以要将async2用Promise包裹起来

  async function async1() {
    console.log('async1 start');
    await async2()
    console.log('async end');
  }
  async function async2() {
    new Promise((resolve, reject) => {
      console.log('async2 start');
      resolve()
    }).then(res => {
      console.log('async2 end');
    })
  }

  // 上面的await代码转换为下面的代码
  async function async1() {
    console.log('async1 start');
    // await async2()
    const p1 = new Promise((res, rej) => {
      new Promise((resolve, reject) => {
        console.log('async2 start');
        resolve()
      }).then(() => {
        console.log('async2 end');
      })
      res(); // 注意这里要把p1的状态变为resolved才能执行接下来的then函数
    })
    p1.then(() => console.log("async end"))
    return p1; // 返回一个Promise
  }

  async1()
  new Promise(resolve => {
    console.log('Promise');
    resolve()
  }).then(res => {
    console.log('Promise end1');
  })
    .then(res => {
      console.log('Promise end2');
    })
    .then(res => {
      console.log('Promise end3');
    })
    .then(res => {
      console.log('Promise end4');
    })
  console.log('script end');
  /*
    结果
    async1 start
    async2 start
    Promise
    script end
    async2 end
    async end
    Promise end1
    Promise end2
    Promise end3
    Promise end4
    */

await转化例子2(个人理解)

async function async1() {
  console.log('async1 start');
  await async2()
  console.log('async end'); 
}
async function async2() {
  return new Promise((resolve, reject) => {
    console.log('async2 start');
    resolve()
  }).then(res => {
    console.log('async2 end');
  })
}

// 上面的代码会被转化为下面的代码(个人理解,可能不准确)
async function async1() {
  console.log('async1 start');
  // await async2()
  new Promise((resolve) => {
    new Promise((res,rej)=>{
      console.log('async2 start');
      res()
    }).then(()=>{
    }).then(()=>{
      resolve()
    })
  }).then(function () {
    console.log('async1 end')
  });
}

async1()
new Promise(resolve => {
  console.log('Promise');
  resolve()
}).then(res => {
  console.log('Promise end1');
})
  .then(res => {
    console.log('Promise end2');
  })
  .then(res => {
    console.log('Promise end3');
  })
  .then(res => {
    console.log('Promise end4');
  })
console.log('script end');
/*
  结果
  async1 start
  async2 start
  Promise
  script end
  async2 end
  async end
  Promise end1
  Promise end2
  Promise end3
  Promise end4
  */


参考:
https://www.ruanyifeng.com/blog/2015/04/generator.html

https://segmentfault.com/a/1190000023442526

https://www.jianshu.com/p/8547a58dcf65

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值