【面试-js】Promise,学会这些就够了

702 阅读3分钟

这是我参与8月更文挑战的第二天,活动详情查看:8月更文挑战

前言

本文将成为promise这个大关卡的通关秘籍。目前,只是分享一些关于promise的总结和手写promise。后续将通过更多的面试题来完善该文。

正文

Promise的这些问题你都知道吗?

promise的定义

  1. promise是异步编程的一种解决方案

promise的用法

  1. promise是一个构造函数 , 通过new生成promise实例
  2. Promise接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
    • resolve函数作用:
      1. 将Promise对象的状态从 pending 变为 resolved
      2. 在异步操作成功时调用
      3. 将异步操作的结果,作为参数传递出去
    • reject函数作用:
      1. 将Promise对象的状态从 pending 变为 reject
      2. 在异步操作失败时调用
      3. 并将异步操作报出的错误,作为参数传递出去

promise的特点

  1. 对象的状态不会受外界影响.peromise对象代表一个异步操作,它有三种状态,只有异步操作的结果,可以决定是哪一种状态,其他都无法影响
  2. 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

promise的优点 (相比于回调地狱,更多的是优化写法,主要是写法上的优化)

  1. 可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
  2. Promise对象提供统一的接口,使得控制异步操作更加容易。

promise的缺点

  1. 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  2. 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  3. 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

如何实现一个简易版Promise

// 手撸一个promise
(function (window) {

    function myPromise(execotor) {
        let self = this
        self.status = 'pending'
        self.data = undefined // 存储resolve的结果
        self.callbacks = [] // {onResolved => {}, onRejected => {}}


        function resolve(value) {
            if (self.status !== 'pending') {
                return
            }
            // 将状态改变成为resolved
            self.status = 'resolved'
            // 存值
            self.data = value
            // 如果有待执行的callback函数,立即异步执行它
            if (self.callbacks.length > 0) {
                setTimeout(() => {
                    self.callbacks.forEach(callbackObj => {
                        callbackObj.onResolved(value)
                    })
                }, 0)
            }
        }

        function reject(value) {
            if (self.status !== 'pending') {
                return
            }
            // 将状态改变成为resolved
            self.status = 'resolved'
            // 存值
            self.data = value
            // 如果有待执行的callback函数,立即异步执行它
            if (self.callbacks.length > 0) {
                setTimeout(() => {
                    self.callbacks.forEach(callbackObj => {
                        callbackObj.onResolved(value)
                    })
                }, 0)
            }
        }

        try {
            execotor(resolve, reject)
        } catch (error) {
            reject(error)
        }

    }

    // promise 原型挂载各种方法
    myPromise.prototype.then = function(onResolved, onRejected) {
        // onResolved  onRejected 存到数组
        // this.callbacks.push({ onResolved, onRejected })
        let self = this
        return new myPromise((resolve, reject) => {
          if (self.status === 'pending') {
            self.callbacks.push({
              onResolved() { onResolved(self.data) },
              onRejected() { onRejected(self.data) }
            })
          } else if (self.status === 'resolved') {
            setTimeout(() => {
              const result = onResolved(self.data)
              if (result instanceof myPromise) {
                result.then(
                  value => { resolve(value) },
                  reason => { reject(reason) }
                )
              } else {
                resolve(result)
              }
              // onResolved(self.data)
            }, 0)
          } else {
            setTimeout(() => {
              onRejected(self.data)
            }, 0)
          }
        })
      }
    myPromise.prototype.catch = function (onRejected) {

    }

    // promise 函数对象上挂载方法
    myPromise.resolve = function (value) {

    }
    myPromise.reject = function (value) {

    }
    myPromise.all = function (value) {

    }
    myPromise.race = function (value) {

    }


    global.myPromise = myPromise
})()

// pending
// resolved
// rejected


let p = new myPromise((resolve, reject) => {
    setTimeout(() => {
        console.log('yes');
        resolve('ok')
    }, 100)
})
p.then(fn)  
.then(
  value => {
    console.log(value , 'test');
    return new Promise()
  }
)

结语

以上只是笔者首日总结,后续还会完善,有用的话欢迎持续关注!!!