js篇-promise/async/await

77 阅读2分钟

Promise是什么

“promise是为解决回调地狱而生”,这句话相信每个前端开发在学习promise的时候都已经了解了。

MDN解释:Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。

promise方法

  • Promise.all(iterable)

    iterable参数中所有的promise对象都返回成功的时候,才触发成功

  • Promise.allSettled(iterable)

    和上面的区别在于,无论iterable参数中的promise对象成功或失败,只要状态已确定,就返回一个promise对象,并带有一个对象数组,对应每个promise的结果。

  • Promise.resolve()

  • Promise.reject()

async函数

MDN解释:async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。asyncawait关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise

简单来说,若搭配await使用, 可以让异步代码以同步方式执行。

怎么用?

举个例子: 有个功能,需要先请求A接口拿到id,再将id上送到B接口。

一般写法:

function request(num) { // 模拟接口请求
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(num * 2);
    }, 1000);
  })
}
request(1).then(res1 => {
  console.log(res1); // 1秒后 输出 2
  request(res1).then(res2 => {
    console.log(res2); // 2秒后 输出 4
  })
})

当这种嵌套多了,代码看起来就很不美观,可读性也比较差。改用async/await

async function fn () { 
    const res1 = await request(5);
    const res2 = await request(res1);
    console.log(res2); // 2秒后输出 20 
} 
fn()

async函数中,await规定了异步操作只能一个一个排队执行,从而达到用同步方式,执行异步操作的效果,这里注意了:await只能在async函数中使用,不然会报错哦

我们看下fn函数执行完返回的是什么

async function fn () {} 
console.log(fn);
console.log(fn());

截屏2022-05-08下午11.41.42.png

可以看出,async函数执行完会自动返回一个状态为fulfilled的Promise,也就是成功状态,但值为undefined,需要在函数中加一个return返回值

再来看个问题,如果await后面接的不是promise,会怎么样呢?

function request(num) { // 去掉Promise
  setTimeout(() => {
    console.log(num * 2)
  }, 1000)
}

async function fn() {
  await request(1) // 2
  await request(2) // 4
  // 1秒后执行完  同时输出
}
fn()

可以看到,await没有起到排队等待的作用

总结async/await函数:

  • await必须与async搭配使用
  • async函数返回的是一个Promise对象,有无值,看有无return
  • await后面最好是接promise,否则可能达不到排队等待的效果(await后面接Promise,才会有阻塞效果)