自定义promise

83 阅读4分钟

1. promise 的理解和使用

1.1 Promise 的理解

抽象表达:Promise 是 JS 中进行异步编程的新的解决方案

具体表达:

  1. 语法上:Promise 是一个构造函数
  2. 功能上:Promise 对象用来封装一个异步操作并可以获取其结果

1.2 Promise 的状态改变

  1. pending 变为 resolved
  2. pending 变为 rejected

只有这两种,且一个 promise 对象只能改变一次。无论成功还是失败,都会有一个结果数据。成功的结果数据一般称为 value,而失败的一般称为 reason。

1.3 Promise 的基本流程

image.png

// 创建一个新的p对象promise
const p = new Promise((resolve, reject) => { // 执行器函数
  // 执行异步操作任务
  setTimeout(() => {
    const time = Date.now() 
    // 如果当前时间是偶数代表成功,否则失败
    if (time % 2 == 0) {
      // 如果成功,调用resolve(value)
      resolve('成功的数据,time=' + time)
    } else {
      // 如果失败,调用reject(reason)
      reject('失败的数据,time=' + time)
    }
  }, 1000);
})

p.then(
  value => { // 接收得到成功的value数据 onResolved
    console.log('成功的回调', value)
  },
  reason => { // 接收得到失败的reason数据 onRejected
    console.log('失败的回调', reason)
  }
)

.then() 和执行器(excutor)同步执行,.then() 中的回调函数异步执行

2 为什么要用 Promise

2.1指定回调函数的方式更加灵活

旧的:必须在启动异步任务前指定

promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定)

2.2支持链式调用,可以解决回调地狱问题

什么是回调地狱?

回调函数嵌套调用,外部回调函数异步执行的结果是其内部嵌套的回调函数执行的条件

setTimeout(function(){
    console.log(1);
    setTimeout(function(){
        console.log(2);
        setTimeout(function(){
            console.log(3);
            setTimeout(function(){
                console.log(4);
                setTimeout(function(){
                    console.log(5);
                },500)
            },400)
        },300)
    },200)
},100);

回调地狱的缺点?

不便于阅读 / 不便于异常处理

解决方案?

promise 链式调用

终极解决方案?

async/await

使用 promise 的链式调用解决回调地狱
doSomething()
  .then(result => doSomethingElse(result))
  .then(newResult => doThirdThing(newResult))
  .then(finalResult => {
  console.log('Got the final result:' + finalResult)
})
  .catch(failureCallback)

回调地狱的终极解决方案 async/await

async function request() {
  try{
    const result = await doSomething()
    const newResult = await doSomethingElse(result)
    const finalResult = await doThirdThing(newResult)
    console.log('Got the final result:' + finalResult)
  } catch (error) {
    failureCallback(error)
  }
}

2.3 如何使用 Promise

API

  1. Promise 构造函数:Promise(excutor) {}

    excutor 函数:同步执行 (resolve, reject) => {}

    resolve 函数:内部定义成功时调用的函数 resove(value)

    reject 函数:内部定义失败时调用的函数 reject(reason)

    说明:excutor 是执行器,会在 Promise 内部立即同步回调,异步操作 resolve/reject 就在 excutor 中执行

    1. Promise.prototype.then 方法:p.then(onResolved, onRejected)

    1)onResolved 函数:成功的回调函数 (value) => {}

    2)onRejected 函数:失败的回调函数 (reason) => {}

    说明:指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调,返回一个新的 promise 对象

  2. Promise.prototype.catch 方法:p.catch(onRejected)

    1)onRejected 函数:失败的回调函数 (reason) => {}

    说明:then() 的语法糖,相当于 then(undefined, onRejected) 4. Promise.resolve 方法:Promise.resolve(value)

    value:将被 Promise 对象解析的参数,也可以是一个成功或失败的 Promise 对象

    返回:返回一个带着给定值解析过的 Promise 对象,如果参数本身就是一个 Promise 对象,则直接返回这个 Promise 对象。

  3. Promise.reject 方法:Promise.resolve(reason)

    reason:失败的原因

    说明:返回一个失败的 promise 对象 Promise.all 方法:Promise.all(iterable)

iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String

说明:返回一个新的 promise,只有所有的 promise 都成功才成功,只要有一个失败了就直接失败 Promise.race方法:Promise.race(iterable)

iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String

说明:返回一个新的 promise,第一个完成的 promise 的结果状态就是最终的结果状态

  1. Promise.reject 方法:Promise.resolve(reason)

reason:失败的原因

说明:返回一个失败的 promise 对象

  1. Promise.all 方法:Promise.all(iterable)

iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String

说明:返回一个新的 promise,只有所有的 promise 都成功才成功,只要有一个失败了就直接失败

  1. Promise.race方法:Promise.race(iterable)

iterable:包含 n 个 promise 的可迭代对象,如 Array 或 String

说明:返回一个新的 promise,第一个完成的 promise 的结果状态就是最终的结果状态

自定义(手写)Promise

四、async 与 await

4.1 async 函数

  1. 函数的返回值为 promise 对象
  2. promise 对象的结果由 async 函数执行的返回值决定
async function fn1() {
  //return Promise.reject(3)
  return Promise.resolve(3)
}
const result = fn1()
result.then(
  value => {
    console.log('onResolved()', value)
  },
  reason => {
    console.log('onRejected()', reason)
  },
)