期约(Promise)与异步函数(一)

文章目录

  • 前言
  • Promise是什么?
  • 常用的方法
    • 构造函数方法
      • Promise.resolve()
      • Promise.reject()
      • Promise.all()
      • Promise.race()
      • Promise.allSettled()
    • 实例方法
      • Promise.then()
      • Promise.catch()
      • Promise.finally()
  • 注意事项
  • Promise的应用
    • 异步加载图片
  • Promise面试题

本篇文章是学完Promise后自己的查漏补缺,因此知识点并不全面。

前言

先了解一下异步函数,看以下异步函数代码:

function double(value) {
	setTimeout(() => setTimeout(console.log, 0, value * 2), 1000);
}

double(3);
// 6  (大约1000ms之后)

为什么说上面是异步函数?

  • setTimeout定义了一个指定时间之后执行的回调函数,即第二个setTimeout。1000毫秒之后,JS会将第二个setTimeout推到自己的消息队列上等待执行。什么时候被执行对JS代码完全不可见。
  • 补充:double()函数在setTimeout成功调度异步操作之后就会立刻退出。

Promise是什么?

promise是一种异步操作的解决方案。

  • 主要可以解决回调嵌套问题,也就是大家说的回调地狱问题。它有三种状态pending、resolved(fulfilled)、rejected。状态一旦转换后就无法改变。
  • 同时promise状态是私有的,也就是外部js代码无法改变其状态,因为为了隔离外部的同步代码
    然后promise的状态改变主要通过resolve()、reject()执行器函数实现。他们两个是同步执行的。
  • promise并非一开始就处于pending状态,而是通过执行刑期函数才能转换状态

Q1:通过什么解决回调地狱问题?
A1:利用每个Promise实例的方法then、catch、finally都会返回一个新的Promise对象的特性,简洁地将异步任务串行化。因为每个后续的处理程序都会等待前一个Promise解决,然后实例化一个新期约并返回它。


常用的方法

构造函数方法

Promise.resolve()

let p1 = new Promise((resolve, reject) => resolve());
let p2 = Promise.resolve()
// 其实p1 === p2为True

除此之外,还有两种情况

  1. 如果没有显式的返回值,则Promise.resolve() 会包装默认的返回值undefined。即这种情况,会输出Promise: undefined
  2. 如果有显式的返回值,则Promise.resolve()会包装这个值。

Promise.reject()

Promise.all()

  • 将多个Promise实例组合成一个Promise的静态方法
  • 合成的Promise只有在每个包含的Promise解决之后才解决,换句话来说: 所有状态都变成 resolved,最终的状态才会变成 resolved
  • 只要有一个变成 rejected,最终的状态就变成 rejected

Promise.race()

  • 将多个Promise实例组合成一个Promise的静态方法
  • 取决于第一个完成Promise实例对象,返回一个包装期约是一组集合中最先解决或拒绝的期约的镜像,换句话来说:如果第一个完成的成功了,那最终的就成功;如果第一个完成的失败了,那最终的就失败。

Promise.allSettled()

  • 只关心操作有没有结束,不关心结果
  • Promise.allSettled() 的状态与传入的Promise 状态无关
  • 永远都是成功的
  • 它只会忠实的记录下各个 Promise 的表现

实例方法

Promise.then()

Promise.prototype.then()方法返回一个新的期约实例

let p1 = new Promise( ()=> {});
let p2 = p1.then();

setTimeout(console.log, 0 p1===p2);  //  返回false
  • 主要用来解决回调地狱问题

Promise.catch()

  • 给期约添加拒绝处理程序,
  • catch 本质上是 then 的特例,相当于Promise.prototype.then(null, onRejected)
  • 一般总是建议,Promise 对象后面要跟 catch 方法,这样可以处理 Promise 内部发生的错误

Promise.finally()

  • 主要用来添加清理代码,状态无关。多数情况原样后传父期约。
  • 当 Promise 状态发生变化时,不论如何变化都会执行,不变化不执行
  • finally() 本质上是 then() 的特例

注意事项

  1. 非重入期
    即同步代码比消息队列中的先执行,因此,跟在then()后面的同步代码一定先于处理程序执行

  2. 邻近处理程序的执行顺序

  3. 期约的基本功能:基于后续期约使用之前期约的返回值来串联期约

  4. 期约扩展中的终止期约期约进度通知

Promise的应用

异步加载图片

    

Promise面试题

  1. 了解 Promise 吗?
  2. Promise 解决的痛点是什么?
  3. Promise 解决的痛点还有其他方法可以解决吗?如果有,请列举。
  4. Promise 如何使用?
  5. Promise 常用的方法有哪些?它们的作用是什么?
  6. Promise 在事件循环中的执行过程是怎样的?
  7. Promise 的业界实现都有哪些?
  8. 能不能手写一个 Promise 的 polyfill?

参考链接:
[1] Promise精选面试题
[2] 你真的懂Promise吗
[3] 前端Promise相关面试题以及知识点
[4] Promise面试题整理
[5] promise经典面试题
[6] JavaScript Promise迷你书(中文版)

你可能感兴趣的:(前端知识点)