Promise 基础教程

发布时间:2023年12月27日

在这里插入图片描述



前言

ES6 入门教程
仓库源码https://github.com/bosombaby/javascript

基础知识

  • promise是 ES6 解决异步编程的方案,可以链式调用,解决回调地狱的问题。提供了统一的错误处理机制,可以更好的控制异步操作的执行顺序。
  • promise 是立即执行函数,resolve reject 都会在事件循环的末尾执行

常见用法

resolve/reject

  • 用于快速创建一个已经处于fulfilled或rejected状态的Promise对象
  • 如果传入的value是一个Promise对象,那么Promise.resolve将直接返回这个Promise对象,否则会返回一个新的 promise 实例

then/catch/finally

const promise = new Promise((resolve, reject) => {
  resolve(1)
})

const p1 = promise
  .then((num) => {
    console.log('第一层 then', num)
    return num + 1
  })
  .then((num) => {
    console.log('第二层 then', num)
    return num + 1
  })
  .then((num) => {
    console.log('第三层 then', num)
    throw Error('出错')
  })
  .catch((err) => {
    console.log('捕获错误', err)
  })

console.log(p1)
  • then 和 catch 方法都返回一个新的 Promise 对象,因此可以使用链式调用的方式处理多个异步操作。
  • 但是我们不使用 resolve 和 reject 操作 promise 状态,而是使用 return 一个函数值改变状态为 成功,throw 一个错误值并使用 catch 接收。如果不返回值,下一个 then 立即执行,没有接收参数
  • catch 放在最后会捕获第一个出错的,finally 最后执行的函数
  • catch 是 then 另一种方式的实现

async

const test1 = async () => {
  return 1
}
  • async 声明的函数返回值会使用 Promise resolve 封装,不写也会
  • 可以在需要的地方使用 Promise.reject 抛出异常

await

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  }, 1500)
})

async function test() {
  console.log('before')
  const data = await promise
  console.log('data', data)
  console.log('after')
}

//上面代码等价于
async function test1() {
  console.log('before')
  promise.then((data) => {
    console.log('data', data)
    console.log('after')
  })
}

test1()
  • await 相当于 Promise 的 then
  • 会把在它后面的同步代码包裹在 then 里面,变成微任务,不是同步任务直接执行

try/catch

// 三、try catch对应Promise.catch
async function test() {
  const promise = Promise.reject('出错') //2
  try {
    console.log('before') //1
    const data = await promise
    console.log('data', data)
  } catch (e) {
    console.error(e) //3
  }
}
  • try…catch 可捕获异常,代替了 Promise 的 catch

promise 手写

从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节 - 掘金

Promise.all

字节飞书面试——请实现promise.all - 掘金

Promise.MyAll = function (promises) {
  let result = []
  return new Promise((resolve, reject) => {
    promises.forEach((item, index) => {
      Promise.resolve(item)
        .then((res) => {
          result[index] = res
          if (Object.keys(result).length === promises.length) resolve(result)
        })
        .catch((err) => {
          reject(err)
        })
    })
  })
}
  • 接受一个可遍历的 promise 实例数组,返回一个 新的 promise 实例,条件与
  • 数组每个实例都成功,输出 resolve 的结果
  • 数组有一个实例 reject 失败,Promise.all() 就失败,调用catch捕获错误

Promise.race

Promise.myRace = function (promises) {
  return new Promise((resolve, reject) => {
    for (let item of promises) {
      Promise.resolve(item).then(resolve, reject)
    }
  })
}
  • Promise.race 从字面意思理解就是赛跑,以状态变化最快的那个 Promise 实例为准
  • 最快的 Promise 成功 Promise.race 就成功,最快的 Promise 失败 Promise.race 就失败

Promise.any

Promise.myAny = function (promises) {
  let result = []
  return new Promise((resolve, reject) => {
    promises.forEach((item, index) => {
      Promise.reject(item).then(resolve, (err) => {
        result[index] = { status: 'rejected', msg: err }
        if (Object.keys(result).length === promises.length) reject(result)
      })
    })
  })
}
  • 和Promise.all 相反,有一个成功就成功,全部失败才失败,条件或

Promise.allSettled

Promise.myAllSettled = function (promises) {
  let result = []
  return new Promise((resolve, reject) => {
    const processResult = (index, msg, status) => {
      result[index] = { status, msg }

      if (Object.keys(result).length === promises.length) resolve(result)
    }

    promises.forEach((item, index) => {
      Promise.resolve(item)
        .then((res) => {
          processResult(index, res, 'fulfilled')
        })
        .catch((err) => {
          processResult(index, err, 'rejected')
        })
    })
  })
}
  • 所有实例都解决之后输出,不会中断执行
  • 是不会变成 rejected 状态的,不管一组 Promise 实例的各自结果如何,Promise.allSettled 都会转变为 fulfilled 状态

常见题目

【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理) - 掘金

文章来源:https://blog.csdn.net/qq_53673551/article/details/135232083
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。