js 基础 - promise & async/await
2023-07-26 02:18:27 # fontend

1. 同步任务和异步任务的区别?

同步任务是指函数按顺序执行,函数执行后,一直要等待函数返回结果才执行下一个函数;异步任务是指调用发出之后,调用不会立刻得到返回结果,而是等调用状态发生变化来通过回调函数通知调用者,这样一次可以做多件事情。

2. js 异步处理发展史

js 中异步处理是相对同步而言的,异步允许我们在执行耗时的任务时,不必等待程序完成,而是继续执行之后的代码,直到任务完成在通知。

callback

异步 callback 其实就是函数,将函数当成参数传递给其他函数,在其他函数执行完毕之后调用该回调函数来达到通知的效果。

优点:

  • 解决了同步问题

缺点:

  • 多层嵌套导致逻辑混乱,耦合性高,错误处理复杂的回调地狱
  • 不能 return
  • 可读性差

Promise

Promise 表示约定 承诺,代表这个约定请求会在未来某个时刻返回数据给调用者,在 MDN 文件中, Promise 是用来表示一个异步操作的最终完成(或失败)及其结果值。

优点:

  • 一定程度解决回调地狱的可读性差的问题
  • 可以讲异步操作以同步操作的流程表达出来,避免层层嵌套的回调函数

缺点:

  • 不能取消
  • 当 pending 状态时,无法得知当前进展到哪一阶段了
  • 内部报错如果没有回调函数,则不会阻塞执行,只会在控制台报错,不会影响外部函数的调用

Generator

Generator 函数是 ES6 中提供的一种异步编程解决方案。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态,需要使用 next() 函数来继续执行下面的代码。

优点:

  • 可以控制函数的执行

缺点:

  • 流程管理不方便

async / await

async 函数是使用 async 关键字声明的 AsyncFunction 构造函数的实例,并且允许在函数中使用 await 关键字,简单来说,它们是基于 promises 的语法糖,使异步代码更易于编写和阅读。

优点:

  • 内置执行器
  • 更广的适用性
  • 语义更清晰 简洁

缺点:

  • 大量的 await 代码会阻塞程序运行,每个 await 都会等待前一个完成

3. promise 的特点

  1. promise 是异步函数,可以通过流程调用的方法设置then 或者catch 方法
  2. promise 创建就立即执行
  3. promise 的状态只有三个,一旦状态改变则不可逆: pending fulfilled rejected

4. 使用 promise 封装 ajax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function _ajax(url, method, data) {
let xhr = new XMLHttpRequest();
return new Promise((resolve, reject) => {
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr.statusText);
}
}
xhr.open(method, url);
xhr.send(data);
})
}

5. 说一下你了解的 promise 的静态方法

  1. all:所有 promise 结果都成功才会执行,但是只要有一个执行失败就会报错
  2. race: 只要有一个发生变化就执行,其状态会传递给该实例对象
  3. allSettled: 所有 promise 对象状态都发生变化为 fulfilled 或者rejected ,
  4. any: 只要有一个参数变成了 fulfilled,就会变成 fulfilled, 如果所有都变成了rejected,则会变成 rejected
  5. resolve:thenable 对象则将该对象转换为 promise 对象,并立即执行 then 方法;参数不是 thenable 对象则将该对象转换为 promise 对象,状态为 resolved
  6. reject:返回一个新的 Promise 对象,该对象以给定的原因拒绝。状态为 rejected
  7. .try : 让函数f如果是同步就同步执行,如果是异步就异步执行,但是现在该方法还在 stage-1,无法使用,bluebirde 可以使用

6. promise.catch 后,后面的.then 还会执行吗?

会执行,因为 catch then finally 都会返回一个新的 promise 实例