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的解析。

  • 相关阅读:
    Intellij IDEA 一些不为人知的技巧
    IDEA配置GIT
    返回数据
    IDEA字体设置
    @RequestParam
    @RequestMapping
    基于jquery fly插件实现加入购物车抛物线动画效果,jquery.fly.js
    js倒计时代码 适合于促销-倒计时代码
    phpstorm 10 注册码
    dispaly:table-cell,inline-block,阐述以及案例
  • 原文地址:https://www.cnblogs.com/jett-woo/p/12554367.html
Copyright © 2011-2022 走看看