首页 > 其他分享 >promise

promise

时间:2024-09-07 17:46:43浏览次数:7  
标签:const onFulfilled state promise result reject onRejected

手写promise --核心功能-->方法-->promise/A+

参考

mdn--promise
.
.

promise中的核心功能

构造函数

    /**
     * 构造函数
     * 1. 定义类
     * 2. 添加构造函数
     * 3. 定义resolve/reject
     * 4. 执行回调函数
    */

    class myPromise {
        constructor(func) {
            const resolve = (result) => {
                console.log('resolve 执行: ' + result);
            }
            const reject = (result) => {
                console.log('reject 执行: ' + result);
            }
            func(resolve, reject)
        }
    }

    // 测试用例
    const p = new myPromise((resolve, reject) => {
        resolve('success')
        // reject('error')
    })

.

状态及原因

一个 Promise 必然处于以下几种状态之一:
待定(pending):初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled):意味着操作成功完成。
已拒绝(rejected):意味着操作失败。
一个待定的 Promise 最终状态可以是已兑现并返回一个值,或者是已拒绝并返回一个原因(错误)。当其中任意一种情况发生时,通过 Promise 的 then 方法串联的处理程序将被调用。如果绑定相应处理程序时 Promise 已经兑现或拒绝,这处理程序将被立即调用,因此在异步操作完成和绑定处理程序之间不存在竞态条件。

如果一个 Promise 已经被兑现或拒绝,即不再处于待定状态,那么则称之为已敲定(settled)。即状态不可逆。
.

    const PENDING = 'pending'
    const FULFILLED = 'fullfilled'
    const REJECTED = 'reject'

    class myPromise {
        // 1. 添加状态
        state = PENDING
        // 2. 添加原因
        result = undefined

        constructor(func) {
            const resolve = (result) => {
                // 3. 调整状态 
                // 4. 添加原因
                if (this.state === PENDING) {
                    this.state = FULFILLED
                    this.result = result
                }
            }
            const reject = (result) => {
                // 3. 调整状态 
                // 4. 添加原因
                if (this.state === PENDING) {
                    this.state = REJECTED
                    this.result = result
                }
            }
            func(resolve, reject)
        }
    }
    // 测试用例
    const p = new myPromise((resolve, reject) => {
        resolve('success')
        reject('error')
        // 状态已敲定为fulfilled, 即便执行reject也不会改变状态了
    })

.

then方法

> 成功和失败回调

onFulfilled 可选
一个在此 Promise 对象被兑现时异步执行的函数。它的返回值将成为 then() 返回的 Promise 对象的兑现值。此函数被调用时将传入以下参数:
value
Promise 对象的兑现值。

如果 onFulfilled 不是一个函数,则内部会被替换为一个恒等函数((x) => x),它只是简单地将兑现值向前传递。

onRejected 可选
一个在此 Promise 对象被拒绝时异步执行的函数。它的返回值将成为 catch() 返回的 Promise 对象的兑现值。此函数被调用时将传入以下参数:
reason
Promise 对象被拒绝的原因。

如果 onRejected 不是一个函数,则内部会被替换为一个抛出器函数((x) => { throw x; }),它会抛出它收到的拒绝原因。

    const PENDING = 'pending'
    const FULFILLED = 'fullfilled'
    const REJECTED = 'reject'

    class myPromise {
        state = PENDING
        result = undefined

        constructor(func) {
            const resolve = (result) => {
                if (this.state === PENDING) {
                    this.state = FULFILLED
                    this.result = result
                }
            }
            const reject = (result) => {
                if (this.state === PENDING) {
                    this.state = REJECTED
                    this.result = result
                }
            }
            func(resolve, reject)
        }

        // 1. 添加实例方法
        then(onFulfilled, onRejected) {
            // 2. 参数判断
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
            onRejected = typeof onRejected === 'function' ? onRejected : x => { throw x }
            // 3. 分情况执行回调
            if (this.state === FULFILLED) {
                onFulfilled(this.result)
            } else if (this.state === REJECTED) {
                onRejected(this.result)
            }
        }
    }

    // 测试用例
    const p = new myPromise((resolve, reject) => {
        // resolve('success')
        reject('error')
    })
    p.then(res => {
        console.log("回调成功: ", res);
    }, err => {
        console.log("回调失败: ", err);
    })

> 异步和多次调用

   const PENDING = 'pending'
    const FULFILLED = 'fullfilled'
    const REJECTED = 'reject'

    class myPromise {
        state = PENDING
        result = undefined
        // 1. 定义实例属性, 保存传入的回调函数, 用对象数组来存
        #handlers = []


        constructor(func) {
            const resolve = (result) => {
                if (this.state === PENDING) {
                    this.state = FULFILLED
                    this.result = result
                    // 3. 调用成功回调
                    this.#handlers.forEach(({ onFulfilled }) => {
                        onFulfilled(this.result)
                    })
                }
            }
            const reject = (result) => {
                if (this.state === PENDING) {
                    this.state = REJECTED
                    this.result = result
                    // 4. 调用失败回调
                    this.#handlers.forEach(({ onRejected }) => {
                        onRejected(this.result)
                    })
                }
            }
            func(resolve, reject)
        }

        then(onFulfilled, onRejected) {
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
            onRejected = typeof onRejected === 'function' ? onRejected : x => { throw x }
            if (this.state === FULFILLED) {
                onFulfilled(this.result)
            } else if (this.state === REJECTED) {
                onRejected(this.result)
            } else if (this.state === PENDING) {
                // 2. 保存回调函数
                this.#handlers.push({
                    onFulfilled, onRejected
                })
            }
        }
    }

    // 测试用例
    const p = new myPromise((resolve, reject) => {
        setTimeout(() => {
            resolve('success')
            reject('error')
        }, 2000)
    })

    p.then(res => {
        console.log("then1: ", res);
    }, err => {
        console.log("then1: ", err);
    })

    p.then(res => {
        console.log("then2: ", res);
    }, err => {
        console.log("then2: ", err);
    })

.

异步任务

> 核心api

为了实现异步任务, vue2使用的核心api有: Promise.then、MutationObserver 、 setImmediate 、 setTimeout

这里我们选用: queueMicrotask 、MutationObserver 、 setTimeout

使用 queueMicrotask 注册的回调函数会在当前宏任务的所有同步代码执行完毕后,但在下一个宏任务(如 DOM 更新、渲染等)开始之前执行。

MutationObserver 接口提供了一种异步监视 DOM 变动的能力。当 DOM 发生变化时,MutationObserver 会触发回调函数。

setTimeout 函数用于设置一个定时器,该定时器在指定的延迟时间后执行一个函数或指定的代码片段。

开启异步任务:

// 1. 异步任务 ==> queueMicrotask
    console.log(1);
    queueMicrotask(() => {
        console.log('queueMicrotask');
    })
    console.log('2');

    // 2. 异步任务 ==> MutationObeserver
    console.log(1);
    // 创建并返回一个新的观察器,它会在触发指定 DOM 事件时,调用指定的回调函数
    const mo = new MutationObserver(() => {
        console.log('mutationObserver');
    })
    // 创建
    const divDom = document.createElement('div')
    // 监听子节点改变
    mo.observe(divDom, { childList: true })
    // 修改内容触发回调函数
    divDom.innerText = 'hehe'
    console.log('2');

    // 3. 异步任务 ==> setTimeout
    console.log(1);
    setTimeout(() => {
        console.log('setTimeout');
    }, 0)
    console.log(2);

.

> 函数封装

       then(onFulfilled, onRejected) {
            onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : x => x
            onRejected = typeof onRejected === 'function' ? onRejected : x => { throw x }
            // 3. 使用封装函数
            if (this.state === FULFILLED) {
                myAsync(() => {
                    onFulfilled(this.result)
                })

            } else if (this.state === REJECTED) {
                myAsync(() => {
                    onRejected(this.result)
                })

            } else if (this.state === PENDING) {
                this.#handlers.push({
                    onFulfilled: () => {
                        myAsync(() => {
                            onFulfilled(this.result)
                        })
                    },
                    onRejected: () => {
                        myAsync(() => {
                            onRejected(this.result)
                        })
                    }
                })
            }
        }
    }

    // 1. 定义函数
    function myAsync(callback) {
        // 2. 调用核心api
        if (typeof queueMicrotask === 'function') {
            queueMicrotask(callback)
        } else if (typeof MutationObserver === 'function') {
            const mo = new MutationObserver(callback)
            const divDom = document.createElement('div')
            mo.observe(divDom, { childList: true })
            divDom.innerText = 'hehe'
        } else {
            setTimeout(callback, 0)
        }

    }

    // 测试用例
    console.log('top');
    const p = new myPromise((resolve, reject) => {
        resolve('success')
        reject('error')
    })
    p.then(res => {
        console.log("then: ", res);
    }, err => {
        console.log("then: ", err);
    })
    console.log('bottom');

.
.
.

链式编程

由于这些方法返回 Promise,因此它们可以被链式调用。

.

标签:const,onFulfilled,state,promise,result,reject,onRejected
From: https://www.cnblogs.com/mandyGuan12/p/18401973

相关文章

  • Promise resolve reject 一直不执行会不会导致内存泄漏
    如果一个Promise一直不resolve或reject,它本身不会直接导致内存泄漏。这是因为Promise对象在其状态变为fulfilled(已解决)或rejected(已拒绝)之后就会变成不可变的状态,并且Promise本身并不会持有对大量数据的引用。然而,有几个方面需要注意:事件监听器和定时器:如果Pr......
  • Chaper 09 深入理解Promise
    欢迎大家订阅【Vue2+Vue3】入门到实践专栏,开启你的Vue学习之旅!文章目录前言一、异步编程二、Promise前言在JavaScript中,异步编程是一个重要的概念。随着应用程序的复杂性增加,处理异步操作的方式也变得更加复杂。Promise是一种用于处理异步操作的对象,它提供了......
  • promise实现一个动态删减并持续执行的队列
     promiseQueue.js:/**@Author:Simoon.jia*@Date:2024-09-0416:00:24*@LastEditors:Simoon.jia*@LastEditTime:2024-09-0416:55:48*@Description:描述*/exportclassPromiseQueue{constructor(){this.queue=[];this.isProcessing=......
  • 九、前端中的异步方法Promise,Promise详解
    文章目录1.Promise简介什么是promise为什么使用Promisepromise中的状态2.Promis的用法1.Promise简介什么是promisePromise是异步编程的一种解决方案,它的构造函数是同步执行的,then方法是异步执行的。为什么使用Promise在JavaScript的世界中,所有代码都是单线程执......
  • [Javascript] Covert async code to sync code with throwing Promise
    constfetch=()=>newPromise((res)=>{setTimeout(()=>res({user:'zhen'}),1150)})globalThis.fetch=fetchasyncfunctiongetUser(){returnawaitfetch()}asyncfunctionm1(){//dosomethingreturnawaitge......
  • webpack4升级到webpack5后部分页面出现Uncaught (in promise) ReferenceError: Cannot
    循环依赖当两个或多个模块相互引用时,就会发生JavaScript中的循环依赖(也称为循环依赖)。这可以是直接引用(A->B->A):或间接( A->B->C->A):虽然循环依赖可能不会直接导致错误,但它们几乎总是会带来意想不到的后果。这可能表现为TypeScript类型检查缓慢或开发服务器频......
  • Promise.all()
    Promise.all()是JavaScript中的一个内置方法,它接受一个Promise可迭代对象,并返回一个新的Promise。这个新Promise仅在可迭代对象中的所有Promise都已成功时才会被满足,或者在可迭代对象中的任何Promise被拒绝时立即被拒绝。Promise.all()的Promise的值是可迭代对象中......
  • 【前端】使用Promise达到循环调用接口的效果
    Promise.all()要使用Promise.all调用同一个异步方法多次并将所有结果收集起来,你可以创建一个包含该方法调用的Promise数组,然后将这个数组传递给Promise.all。示例:假设你有一个异步方法fetchData(id),你想针对一组ID调用它并等待所有结果。asyncfunctionfetchData(id){......
  • 手写Promise
    实现功能如下:Promise构造函数promise实例then方法pomise实例catch方法promise实例finally方法Promise静态resolve方法Promise静态reject方法Promise静态all方法备注:参照渡一教育视频代码:1constPending='pending';2constFullFiled='fulfilled';3con......
  • lua版promise实现 - 结束
    相比V1版本这边做了以下修改:1)函数命名尽量与js版保持一致,js中的then在这边叫Next(因为then是lua的关键字)2)m_DoNextObj这边变成了一个列表,这样改动的结果就是:之前对象间会组成单向链表;这边是一个单向的树。3)m_DoNextObj.run函数这边改成了m_OnFulfilled和m_OnRejected函数(......