前端学习:异步编程(Promise和异步函数)

本文章旨在梳理JavaScript异步编程知识点,大多引用自《JavaScript高级程序设计》(第4版)。

异步编程

JS的单线程和异步编程

为什么javaScript是单线程的,却可以处理异步函数呢?
这个问题的答案很简单,JS是单线程事件循环模型,所有的同步任务放在主线程(或称为同步线程)的执行栈里,按照先进先出的顺序在主线程执行,当出现一个异步任务时,浏览器创建一个异步线程来执行异步函数,并将回调函数放入任务列表中,当主线程执行完当前执行栈中的任务后,再顺序执行回调函数任务列表里的任务。
因此虽然JavaScript是单线程的,但异步任务仍然是多线程完成的,且异步任务的回调函数又是由主线程来完成的。

回调地狱

以往的JS中,支持定义回调函数的方式来表示异步函数的完成,此时如果想要串联多个异步操作,就要在回调函数里嵌套异步任务再嵌套回调函数。。。从而产生了回调地狱。
回调地狱的解决方法——ES6的新引用类型:Promise类型

Promise

什么是Promise?Promise有哪些状态?

  • Promise是ES6的新引用类型,可以更加优雅的组织异步逻辑。
  • Promise有三种状态:pending、resolved和rejected。
  • Promise的状态不可逆,Promise的落定状态一旦确定,就是不可逆转的。
  • Promise的两大用途:
    (1)抽象的表示一个异步操作,Promise的状态表示异步操作是否完成。即告诉我们一个异步操作是否完成。
    (2)Promise封装的异步操作会实际生成某个值,这个值可以被我们访问到。

Promise有哪些实例方法?(then、catch、finally)

  • 为什么Promise可以使用then来实现链式调用?
    then方法实现了一个Thenable接口,每个then方法返回一个新的Promise实例,这个新的Promise又可以继续调用then方法。
  • then方法放入的两个参数,第一个是onResolved处理程序,第二个是onRejected处理程序,两个参数互斥。
  • onRejected处理程序用于捕获异步错误的任务,由于捕获错误成功(任务执行成功),那么它返回一个resolved的Promise。(注意onResolved处理程序抛出异常则返回一个rejected的Promise,但却会把错误对象包装在一个resolved的Promise中返回)
  • catch方法放入的是onRejected处理程序。
  • finally方法不管Promise的状态是resolved还是rejected都会执行,一般用于添加清理代码。

非重入特性

当Promise的状态确定以后,与它相关的处理程序不会立即执行,而是放到之前所说的任务队列里,等待主线程执行完所有目前的同步任务后才会执行(会按照添加他们的顺序依次执行)。

Promise的链式调用

  • Promise的链式调用目的是串联化异步任务,原理是每一个后续处理程序都会等待前一个Promise解决,然后实例化一个新的Promise并返回。
  • Promise的链式调用解决了回调地狱的问题。

Promise的静态方法:Promise.all()、Promise.race()

Promise.all()

  • Promise.all()接收一个可迭代对象,返回一个新的Promise(注意即使所有期约都成功也返回的是一个Promise,这个新的Promise的解决值是包含所有Promise解决值的数组)。
  • 如果至少有一个包含的Promise待定,那么合成的Promise也待定(pending),如果有一个Promise拒绝,那合成的Promise也拒绝(rejected)
  • 只有所有Promise都成功解决,那合成期约的解决值是包含所有Promise解决值的数组(数组顺序按照迭代器的顺序)
  • 如果有Promise拒绝,那么第一个拒绝的Promise会将自己的拒绝理由作为合成期约的拒绝理由。

Promise.race()

  • Promise.race()接收一个可迭代对象,返回一个新的Promise。
  • 返回一组集合中最先解决或拒绝(即最先落定)的Promise的镜像。
  • 不管是all还是race,合成期约会静默处理所有包含期约的拒绝操作,不会有错误跑掉。

Promise的应用

函数合成

将多个函数合成一个函数,利用链式调用的参数传递。

Promise的封装(实现一个Promisify函数)

将原本需要通过传入回调参数来实现回调执行(或者叫同步执行)改为利用promise的.then的方式来调用,从而实现逻辑上的同步操作。
重点:参数传递

function promisify(func) {
   
  return function (...args) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值