zoukankan      html  css  js  c++  java
  • 手写Promise

    手写Promise

    在本文中,我们通过手写实现一个符合Promise/A+规范的Promise来深入了解Promise, 而且手写Promise也是一道大厂面试常考题。在进入正题之前,推荐各位阅读一下Promise/A+规范 (网上有很多解释,可以自行搜索),这样才能更深入的理解本文中的代码。

    实现一个简易版的Promise

    先来搭建函数的大体框架

    // 创建3个常量表示Promise的3个状态
    const PENDING = 'pending'
    const RESOLVED = 'resolved'
    const REJECTED = 'rejected'
    
    function MyPromise(fn){
        // 创建常量that保存this, 因为Promise代码可能会异步执行,用于获取正确的this对象
        const that = this
        // 一开始Promise的状态应该是pending
        this.state = PENDING
        // value变量用于保存resolve或者reject中传入的值
        that.value = null
        // 用于保存then中的回调,因为当执行完Promise时状态可能还是等待中,这时候应该把 then 中的回调保存起来用于状态改变时使用
        that.resolvedCallbacks = []
        that.rejectedCallbacks = []
    
        // 待完善 resolve 和 reject 函数
        // 待完善执行 fn 函数
    }

    接下来完善resolvereject函数,添加在MyPromise内部

    // 待完善的 resolve 和 reject 函数
    function resolve(value) {
        console.log('执行resolve')
        // 首先两个函数都得判断当前状态是否为等待中,因为规范规定只有等待态才可以改变状态
        if (that.state === PENDING) {
            // // 将当前状态更改为对应状态,并且将传入的值赋值给value
            that.state = RESOLVED
            that.value = value
            // 状态改变时,指定回调
            that.resolvedCallbacks.map(cb => cb(that.value))
        }
    }
    function reject(value) {
        // 首先两个函数都得判断当前状态是否为等待中,因为规范规定只有等待态才可以改变状态
        if (that.state === PENDING) {
            // 将当前状态更改为对应状态,并且将传入的值赋值给value
            that.state = REJECTED
            that.value = value
            // 状态改变时执行回调
            that.rejectedCallbacks.map(cb => cb(that.value))
        }
    }

    完成以上两个函数后,就该实现如何执行Promise中传入的函数了

    // 待完善执行 fn 函数
    try {
        // 执行传入的参数并且将之前两个函数当做参数传进去
        fn(resolve, reject)
    }catch (e) {
        // 可能执行函数过程中会遇到错误,需要捕获错误并且执行 reject 函数
        reject(e)
    }

    最后实现较为复杂的then函数

    MyPromise.prototype.then = function (onFulfilled, onRejected) {
        console.log('执行then')
        const that = this
        // 判断两个参数是否为函数类型,因为这两个参数是可选参数,如果不是函数,则直接返回相应的value或reason
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
        onRejected = typeof onRejected === 'function' ? onRejected : r => {
            throw r
        }
    
        // 当函数是等待态时,就往回调函数数组中push函数
        if (that.state === PENDING) {
            console.log('Pending')
            that.resolvedCallbacks.push(onFulfilled)
            that.rejectedCallbacks.push(onRejected)
        }
        // 如果不是等待态,就执行相对应的函数
        if (that.state === RESOLVED) {
            onFulfilled(that.value)
        }
    
        if (that.state === REJECTED) {
            onRejected(that.value)
        }
    }

    最后,使用MyPromise

    new MyPromise((resolve, reject) => {
        // 这里是异步,所以回调会先存入resolvedCallbacks中
        setTimeout(() => {
            resolve(1)
        }, 0)
        }).then(value => {
            console.log(value)
        })

    以上就是简单版的Promise实现,接下来实现更为完整版的Promise的解析。

  • 相关阅读:
    Leetcode Spiral Matrix
    Leetcode Sqrt(x)
    Leetcode Pow(x,n)
    Leetcode Rotate Image
    Leetcode Multiply Strings
    Leetcode Length of Last Word
    Topcoder SRM 626 DIV2 SumOfPower
    Topcoder SRM 626 DIV2 FixedDiceGameDiv2
    Leetcode Largest Rectangle in Histogram
    Leetcode Set Matrix Zeroes
  • 原文地址:https://www.cnblogs.com/jett-woo/p/12554367.html
Copyright © 2011-2022 走看看