首页 > 其他分享 >Promise是如何实现then的链式调用的?

Promise是如何实现then的链式调用的?

时间:2025-01-11 14:47:04浏览次数:1  
标签:调用 self 链式 value reason Promise result reject

Promise 对象的 then 方法返回一个新的 Promise 对象,这是实现链式调用的关键。每一个 then 都会返回一个新的 Promise,而这个新的 Promise 的结果取决于 then 里面的回调函数的返回值。

以下是一个简化的 Promise 和 then 方法的实现,用于说明链式调用是如何工作的:

function Promise(executor) {
    let self = this;
    self.status = 'pending';
    self.value = undefined;
    self.reason = undefined;
    self.onResolvedCallbacks = [];
    self.onRejectedCallbacks = [];

    function resolve(value) {
        if (self.status === 'pending') {
            self.status = 'resolved';
            self.value = value;
            self.onResolvedCallbacks.forEach(fn => fn());
        }
    }

    function reject(reason) {
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.reason = reason;
            self.onRejectedCallbacks.forEach(fn => fn());
        }
    }

    try {
        executor(resolve, reject);
    } catch (err) {
        reject(err);
    }
}

Promise.prototype.then = function(onResolved, onRejected) {
    let self = this;
    return new Promise((resolve, reject) => {
        function handledResolve(value) {
            try {
                let result = onResolved(value);
                result instanceof Promise ? result.then(resolve, reject) : resolve(result);
            } catch (err) {
                reject(err);
            }
        }

        function handledReject(reason) {
            try {
                let result = onRejected(reason);
                result instanceof Promise ? result.then(resolve, reject) : reject(result);
            } catch (err) {
                reject(err);
            }
        }

        switch (self.status) {
            case 'pending':
                self.onResolvedCallbacks.push(() => handledResolve(self.value));
                self.onRejectedCallbacks.push(() => handledReject(self.reason));
                break;
            case 'resolved':
                handledResolve(self.value);
                break;
            case 'rejected':
                handledReject(self.reason);
                break;
        }
    });
};

在这个简化的实现中,你可以看到 then 方法创建并返回了一个新的 Promise 对象。这个新的 Promise 对象的执行器函数会处理原始 Promise 对象的解决或拒绝,并根据 then 方法中提供的回调函数(onResolvedonRejected)来决定新的 Promise 对象的状态。

如果原始 Promise 对象的状态是 'pending',那么新的 Promise 对象会将自己的回调函数添加到原始 Promise 对象的回调函数队列中,以便在原始 Promise 对象的状态改变时执行。如果原始 Promise 对象的状态已经是 'resolved' 或 'rejected',那么新的 Promise 对象会立即执行相应的回调函数。

这样,当你链式调用 then 方法时,你实际上是在创建一个 Promise 对象的链,每个对象都依赖于前一个对象的状态,并根据前一个对象的状态来决定自己的状态。

标签:调用,self,链式,value,reason,Promise,result,reject
From: https://www.cnblogs.com/ai888/p/18665644

相关文章

  • 使用JavaScript实现一个Promise的队列
    在前端开发中,你可能想要按顺序执行一系列的异步操作,即使这些操作本身并不依赖彼此的结果。这通常可以通过创建一个"Promise队列"来实现,即将Promise对象放入一个数组中,然后按顺序执行它们。以下是一个简单的示例,演示如何使用JavaScript实现一个Promise队列:classPromiseQueue{......
  • 请说说你对PromiseA+规范的了解
    PromiseA+规范是前端开发中关于异步操作处理的一个重要规范,它定义了Promise对象的行为和交互方式,为异步编程提供了统一的模型。以下是我对PromiseA+规范的了解:一、PromiseA+规范的基本概念Promise:Promise是一个有then方法的对象或函数,其行为遵循PromiseA+规范。它代表了一个异......
  • promise有哪些状态?
    在前端开发中,Promise是一个重要的概念,它用于处理异步操作。Promise对象代表一个异步操作的最终完成(或失败)及其结果值的状态。一个Promise对象有三种状态,这些状态是:Pending(进行中):这是Promise对象的初始状态,表示异步操作尚未完成,处于等待状态。在Promise被创建时,它默认处于这个状......
  • 如何避免函数调用栈溢出?
    在前端开发中,函数调用栈溢出通常是由于递归调用过深或者大量嵌套函数调用导致的。为了避免函数调用栈溢出,你可以采取以下几种策略:优化递归算法:尾递归优化:尾递归是一种特殊的递归形式,其中递归调用是函数体中最后执行的语句。通过优化尾递归,你可以将递归转换成循环,从而避免栈溢......
  • Android 14.0 app调用hal层接口功能实现系列一(hal接口的创建)
    1.前言在14.0的系统rom定制化开发中,对于一些需要在app中调用hal层的一些接口来实现某些功能而言,就需要打通app到hal的接口,实现功能需求,这一节首先讲在hal层中提供接口然后通过jni来调用,首先来建立hal层的相关接口和c++文件,提供hal层供上层调用的接口2.app调用hal层接口功能实......
  • 使用LangChain集成ForefrontAI进行LLM调用
    在本篇文章中,我们将深入探讨如何在LangChain中集成使用ForefrontAI。本文将分为两部分:安装与设置,以及如何使用ForefrontAI的封装器。技术背景介绍LangChain是一个用于构建LLM(大型语言模型)应用程序的强大框架。ForefrontAI作为其中一个支持的LLM提供商,为开发者提供了灵活的......
  • 深度解析微信小程序数据预拉取API调用的问题与使用方法
    了解到通过配置数据预拉取可以在更早的生命周期调用网络请求以提升首屏数据的渲染速度,但通过官方文档和网上各种文章解析,都没有把API给解释明白且社区存在大量反馈问题,通过深入的了解和调试,故写下本解析文章。官方文档说明首先配置预拉取地址信息和在开发者工具开启数据预......
  • 用python调用AlistClient 批量递归下载百度网盘指定目录文件,基于Alist
    importosimportrequestsfromalistimportAlistClientfromurllib.parseimportunquote,urlparsedefdownload_file(url,local_path):response=requests.get(url,stream=True)total_size=int(response.headers.get('content-length',0))......
  • FastApi框架异步调用同步问题
    Fastapi项目,在接口中调用同步方法,如果该同步方法,耗时较长(比如连接redis超时),会造成整个项目接口的阻塞,这是任何接口的访问都会被阻塞超时一、为什么会阻塞FastAPI是基于异步框架(如asyncio或anyio)构建的,它的核心是一个事件循环(EventLoop)。事件循环负责调度和执行所有的异步......
  • 多继承背景下的调用逻辑【MRO】
    MROMRO(MethodResolutionOrder,方法解析顺序)是指在多继承情况下,Python解释器按照特定的顺序来查找和调用方法的规则。classA:passclassB:passclassC(A,B):passprint(C.__mro__)#输出:(<class'__main__.C'>,<class'__main__.A'>,<class......