不是所有的链式调用,都是Promise函数,Promise 规范及其衍生的 Promise/A+ 规范

文章目录

    • 提问
    • [Promise 规范](#Promise 规范)
    • [Promise/A+ 规范](#Promise/A+ 规范)
    • 回答
    • 小结

提问

jQuery大家多多少少都有用过或者听说过,曾经也是很受欢迎,之所以受欢迎那就离不开它的链式调用,那么我想问个问题它是jQuery大家多多少少都有用过或者听说过,曾经也是很受欢迎,之所以受欢迎那就离不开它的链式调用,那么我想问个问题它是Promis函数吗?

以下所写的函数是不是一个Promise函数呢?

javascript 复制代码
function MyPromise(executor) {
    let onFulfilled, onRejected;
    let state = 'pending'; // 初始状态
    let value; // 成功时的值
    let reason; // 失败时的原因

    // resolve 方法
    function resolve(newValue) {
        if (state === 'pending') {
            state = 'fulfilled';
            value = newValue;

            // 如果 onFulfilled 是函数,调用它
            if (typeof onFulfilled === 'function') {
                onFulfilled(value);
            }
        }
    }

    // reject 方法
    function reject(newReason) {
        if (state === 'pending') {
            state = 'rejected';
            reason = newReason;

            // 如果 onRejected 是函数,调用它
            if (typeof onRejected === 'function') {
                onRejected(reason);
            }
        }
    }

    // 执行 executor 函数
    executor(resolve, reject);

    // then 方法
    this.then = function (callback) {
        // 只支持 onFulfilled
        onFulfilled = callback; // 这里不处理 onRejected

        // 返回 this,允许链式调用
        return this;
    };
}

// 使用 MyPromise
const promise = new MyPromise((resolve, reject) => {
    resolve("成功结果");
});

// 符合 Promise 规范,但不符合 Promise/A+ 规范
promise.then(result => {
    console.log(result); // 输出: 成功结果
});

// 继续链式调用
promise.then(result => {
    console.log("进一步处理:", result); // 这个输出将是 undefined
});

Promise 规范

Promise 是一种用于表示异步操作的对象,允许我们以一种可预测的方式处理异步结果。Promise 规范的主要目标是定义 Promise 对象的行为,包括其状态、方法及其与其他 Promise 的交互。

1.1 Promise 的状态

Promise 有三种状态:

  • Pending(待定):初始状态,既不是成功也不是失败。
  • Fulfilled(已完成):异步操作成功完成,Promise 进入已完成状态。
  • Rejected(已拒绝):异步操作失败,Promise 进入已拒绝状态。

1.2 Promise 的方法

Promise 提供了几个关键方法来处理异步操作:

1.2.1 Promise构造函数

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
    // 执行异步操作
    if (/* 操作成功 */) {
        resolve(result); // 进入 Fulfilled 状态
    } else {
        reject(error); // 进入 Rejected 状态
    }
});
  • resolve(value):将 Promise 的状态从 Pending 改为 Fulfilled,并传递结果值。
  • reject(reason):将 Promise 的状态从 Pending 改为 Rejected,并传递失败原因。

1.2.2 then 方法

javascript 复制代码
myPromise.then(onFulfilled, onRejected);
  • onFulfilled:当 Promise 进入 Fulfilled 状态时调用的函数。
  • onRejected:当 Promise 进入 Rejected 状态时调用的函数。

1.2.3 catch 方法

javascript 复制代码
myPromise.catch(onRejected);
  • 该方法用于处理 Promise 被拒绝时的错误,等效于 .then(null, onRejected)

1.2.4 finally 方法

javascript 复制代码
myPromise.finally(onFinally);
  • 无论 Promise 最终状态是 Fulfilled 还是 Rejected,都会执行的操作。

Promise/A+ 规范

Promise/A+ 是对 Promise 的一种标准化规范,旨在确保不同实现之间的互操作性。以下是一些关键方面:

2.1 状态的定义

根据 Promise/A+ 规范,Promise 必须有以下三个状态,并且状态转换是不可逆的:

  • 从 Pending 到 Fulfilled。
  • 从 Pending 到 Rejected。

2.2 then 方法的实现

  • then 方法接受两个参数(onFulfilledonRejected),并且这两个参数都应该是可选的。
  • 如果 onFulfilled 不是函数,Promise 应当将其视为一个返回值。
  • 如果 onRejected 不是函数,Promise 应当将其视为一个抛出的错误。

2.3 链式调用

  • then 方法必须返回一个新的 Promise,以便支持链式调用。
  • 如果 onFulfilledonRejected 返回一个 Promise,则返回的 Promise 应当与该 Promise 具有相同的状态。
  • 如果返回的是一个普通值,则新的 Promise 应当被 Fulfilled,值为返回的普通值。
  • 如果返回的是一个抛出的错误,则新的 Promise 应当被 Rejected,原因是错误。

2.4 异常处理

  • 如果在 onFulfilledonRejected 中抛出错误,返回的 Promise 应当被 Rejected,原因是该错误。
  • 错误处理应按照"错误传播"的机制进行,这样可以确保调用链上的错误能够被捕获。

回答

回答下最开始问题,其实可以说是一个Promise函数,但不是一个标准的Promise函数,并不符合Promise/A+ 规范,而现在使用的几乎都是ES6里的Promise函数,也就是Promise/A+规范

jQuery 提供的 Deferred 和 Promise 对象在某种程度上实现了 Promise 的概念,但它们并不完全遵循 ECMAScript 6 (ES6) 中的原生 Promise 规范或 Promise/A+ 规范。以下是一些详细的分析:

jQuery 的 Deferred 和 Promise

  1. 基本特性:
    • jQuery 的 Deferred 对象可以用于处理异步操作,允许注册多个回调函数。
    • Promise 对象是 Deferred 的一部分,提供了 then()done()fail()always() 等方法。
  2. 与 Promise/A+ 的不一致:
    • 状态不可变:jQuery 的 Deferred 在状态上更为灵活,可以在创建后多次调用 resolvereject,而原生 Promise 一旦变更状态后就无法改变。
    • 回调注册:jQuery 的 then 方法在处理回调时,允许传递多个回调,而 Promise/A+ 规范要求 then 方法只接受两个参数(onFulfilledonRejected)。
    • 链式调用:jQuery 的 Promise 方法返回的对象并不总是新的 Promise 对象,从而可能导致链式调用时的行为不符合 Promise/A+ 规范。

结论

  • 不符合 Promise/A+ 规范:jQuery 的 DeferredPromise 实现并不完全符合 Promise/A+ 规范,因此在某些情况下它们的行为与原生 Promise 不一致。
  • 在某些使用场景下可用:尽管不完全符合规范,jQuery 的 DeferredPromise 仍然在处理异步操作时非常有用,特别是在结合 jQuery 的其他功能时。

总的来说,虽然 jQuery 的 DeferredPromise 提供了一些 Promise 的特性,但它们并不完全遵循现有的 Promise 规范或 Promise/A+ 规范。如果需要一个符合规范的 Promise 行为,建议使用 ES6 原生 Promise。

小结

Promise 规范和 Promise/A+ 规范共同定义了异步编程的行为,从状态管理到方法实现,确保了 Promise 的一致性和可预测性。理解这些规范有助于在使用 Promise 处理异步操作时更有效地编写代码,并确保代码在不同环境中的兼容性。

相关推荐
锦瑟弦音2 小时前
跑酷游戏开发笔记3 && 游戏开始场景 cocos 3.8.7
javascript·笔记·游戏
ttod_qzstudio3 小时前
Vue 3 的魔法:用 v-bind() 让 CSS 爱上 TypeScript 常量
css·vue.js·typescript
MoonBit月兔3 小时前
海外开发者实践分享:用 MoonBit 开发 SQLC 插件(其二)
开发语言·javascript·数据库·redis·mysql·moonbit
前端李易安3 小时前
ERROR in ./node_modules/vue-router/dist/vue-router.mjs 被报错折磨半天?真相竟是……
前端·javascript·vue.js
monkey_slh3 小时前
JS逆向实战——最新某东cfe滑块
开发语言·前端·javascript
禅思院3 小时前
在win10上配置 Rust以及修改默认位置问题
开发语言·前端·后端·rust·cargo·mingw64·cargo安装位置
2503_928411563 小时前
12.17 vue递归组件
前端·javascript·vue.js
暴富的Tdy3 小时前
【使用 Vue2 脚手架创建项目并实现主题切换功能涵盖Ant-Design-Vue2/Element-UI】
vue.js·elementui·anti-design-vue·vue切换主题
LYFlied3 小时前
【每日算法】LeetCode 79. 单词搜索
前端·算法·leetcode·面试·职场和发展