[JavaScript理论学习] 什么是Promise (含如何判断一个值是Promise)

这篇具有很好参考价值的文章主要介绍了[JavaScript理论学习] 什么是Promise (含如何判断一个值是Promise)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是Promise (含如何判断一个值是Promise)

本文旨在对 Promise 的规范进行解释, 便于读者在学习 Promise 的过程中梳理 Promise 之间的操作关系, 不对具体的代码实现和Promise用法进行解释.

比如, 为什么 [MDN-await] 中要提及一个 thenable 对象, 而且这个 thenable 对象还可以和 Promise 实例一样使用 await 等待处理, 这就涉及到了下面的内容.

由于笔者编程水平的限制, 不可避免存在错漏或者语意不清的地方.

Promise A+ 规范

参考资料: [Promises/A+]

在 ES6 之前,社区已经有了 Promise A+ 规范, 该规范定义了 Promise 的行为和接口. 根据规范, 任何具有 .then() 方法的函数或对象都可以被认为是一个 Promise ,并且可以进行 Promise 之间的操作。

这个具有 .then() 方法的函数/对象被称为 thenable 对象, 你可以在 [MDN-Promise#thenable] 和 [Promises/A+] 查阅到相关资料.

如果读者您熟悉 ES6 中的 Promise , 那么对 Promise A+ 规范一定不陌生, 因为 ES6 中的 Promise 就是基于 Promise A+ 规范的官方实现和拓展. 我们可以将 ES6 的 Promise 称为 Promise 对象, 在 ES6 之前, 第三方库实现的 Promise A+ 规范对象称为 thenable 对象.

该规范旨在于统一 JS 中的异步实现, 进而让回调变得可控, 避免出现回调地狱. 早在 ES6 之前, 就有很多第三方库遵守和支持这个规范. 比如 jQuery 中的 $.ajax() / $.get() 等方法返回的就是一个 JQuery 实现的 thenable 对象.

因为在 Promise A+ 规范在社区中被大范围认可之前, 各种第三方库(包括 JavaScript 官方) 对于异步的实现都是不统一的.

这就导致了不同的库之间如果存在异步, 就很难互相操作.

比如一个 三方库A 使用异步在 A库 内部某个函数执行的时候返回了数据 DataA, 现在我需要调用另一个 第三方库B 在获取到 DataA的时候, 执行另外一个异步操作. 这是很难操作的, 因为没有一个统一的规范告诉 B库, 我该什么时候执行, 每个开发者的实现是不同的, 为了实现这一点可能就需要建立各种各样的回调函数来相互通讯.

如果时间放眼到现在, 当然很容易实现, 只需要一行代码: A.then(dataA => { B(dataA).then() });, 这便是 Promise A+ 规范的作用.

ES6 Promise

基于 Promise A+ 规范, 在 ES6 中新增了一个构造函数 Promise, 通过实例化 Promise (new Promise()) 可以新建一个 Promise 对象, 这个对象是一个符合 Promise A+ 规范的对象 .

如果为了便于理解, 我们可以将 Promise 对象 简单理解为一个继承了 thenable 对象 的对象.

不过在 Promise A+ 的基础上, ES6还拓展了更多的功能, 比如 .catch() 方法, .finally() 方法 , 静态方法 Promise.all() 等等, 具体可以查阅 MDN-Promise .

需要另外了解的一点是, .catch( (error) => {} )方法本质上就是第一个参数传入了空参数的.then( undefined, (error) => {} )方法.

最小实现的 Promise 和最大实现的 Promise

综上所述, 我们可以将 Promise A+ 规范规定的 Promise 称为最小实现的 Promise, 也就是 thenable 对象; 将 ES6 的 Promise 成为最大实现的 Promise, 即 Promise 对象.

如果要检测一个值是否为最小实现的 Promise , 只需要检测是否函数/对象, 并且存在 .then() 方法即可.

如果要检测一个值是否为最大实现的 Promise, 则只需要在上面的检测的基础上, 添加一个 .finally() 方法的检测.


兼容性

由于 ES6 中的 Promise 是吸取 Promise A+ 规范制定的, 所以也沿用了 Promise A+ 规范中的内容, 比如很少被注意的一点 Promise A+ Point-46: 只要有暴露了兼容 Promise A+ 规范 .then() 方法的 thenable 对象, 那么这个 thenable 对象就能够和其它兼容的 thenable 对象互相操作.

This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.

所以像是 ES6 的 Promise.all(), ES7 的 asnyc / await, 都是使用的最小实现 Promise 判断, 也就是如果传入的对象 / 函数存在 .then() 方法, 那么就会被当做一个 Promise 去等待兑现 / 拒绝.


示例 - async / await

( async () => {
    /* await 一个Promise */
    console.log( await new Promise( ( resolve ) => {
        resolve( 'resole a Promise.' );
    } ) );
    // -> 'resole a Promise.'

    /* await 一个自定义的thenable对象 */
    console.log( await {
        then( resolve ) {
            resolve( 'resole a thenable object.' )
        }
    } );
    // -> 'resole a thenable object.'

    /* await 非Promise非thenable对象, 比如一个空对象 */
    console.log( await {} );
    console.log( await 1 );
    // -> {}
    // -> 1
    // 返回表达式原先的值

    /* await 一个空的thenable对象 */
    console.log( await { then() {} } );
    // 无输出
    // 因为这是一个 thenable 对象, 所以 await 会暂停当前执行进程而不是像上面的表达式一样直接返回表达式的值
    // 因为没有 resolve 或者 reject, 当前执行进程被 await 暂停之后永远不会恢复进程, 等同于当前执行进程(当前async函数)被阻塞了

    console.log( 'Test' );
    // 不会有输出了
} )();

什么是Promise

在 Promise A+ 规范中, Promise 就是一个具有 .then() 方法的函数或者对象.

在 ES6(ES2015) 中, Promise 是一个构造函数, 通过这个构造函数可以实例化一个符合 Promise A+ 规范的对象.

在 ES7(ES2016) 及其之后的版本, 还可以使用 await / async 去调用所有符合 Promise A+ 规范的对象, 包括一些第三方库自己实现的符合 Promise A+ 规范的对象.

只要是符合 Promise A+ 规范的 Promise , 那么它们之间就可以互相操作.

工具函数, 检测一个对象是否为Promise

通常不会直接使用类似value instanceof Promise的判断, 而是给予 Promise A+ / ES6 Promise 规范判断.

最小限定的检测, 检测是否为 thenable 对象.

/**
 * 判断传入参数是否为 Promise (最小实现)
 * @param { any } value
 * @return { boolean } 是否为 Promise
 * @description 代码源于第三方库 is-promise
 * @tutorial https://www.npmjs.com/package/is-promise
 * */
function isPromise( value ) {
	return !!value
		&& (typeof value === 'object' || typeof value === 'function')
		&& typeof value.then === 'function';
}

取消了 typeof value === 'function' 的判断, 因为通过 new Promise() 实例化的值一定是一个对象.

如果想更严格一下, 还可以将 .catch() 方法也加进判断, 也有些工具函数只判断 .then() 方法和 .catch() 方法是否存在, 这只看使用者是想如何限定 Promise 的范围.文章来源地址https://www.toymoban.com/news/detail-698927.html

/**
 * 判断传入参数是否为 Promise (最大实现)
 * @param { any } value
 * @return { boolean } 是否为 Promise
 * */
function isStrictPromise( value ) {
	return !!value
		&& typeof value === 'object'
		&& typeof value.then === 'function'
		&& typeof value.finally === 'function';
}

到了这里,关于[JavaScript理论学习] 什么是Promise (含如何判断一个值是Promise)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 理论学习-ARM-内核

    为了提高学习效率,我们要提前想好学习策略。 首先,使用频率越高的知识点,越要首先学习。假使,我们学习了一个知识点,能覆盖工作中80%的工作量,那是不是很夸张的学习效率?! 其次,有两种覆盖知识点,梳理知识点的策略。一种是将知识按体系划分,挨个学习,

    2024年02月22日
    浏览(40)
  • Transformer理论学习

    Transformer出自于论文《attention is all you need》。 一些主流的序列模型主要依赖于复杂的循环结构或者CNN,这里面包含了编解码器等。而Transformer主要的结构是 基于注意力机制 ,而且是用多头注意力机制去替换网络中的循环或者CNN(换言之就是 transformer 这个网络模型是不需要循环

    2024年02月13日
    浏览(43)
  • 孤子理论学习(一)

    最简单的波的典型例子就是声波和电磁波,它们可以用下面的方程描述:   ( ∂ 2 ∂ t 2 − v 0 2 ∂ 2 ∂ x 2 ) f ( x , t ) = 0   (1.1) (frac{partial^2}{partial t^2}-v_0^2frac{partial^2}{partial x^2})f(x,t)=0 ,tag{1.1}   ( ∂ t 2 ∂ 2 ​ − v 0 2 ​ ∂ x 2 ∂ 2 ​ ) f ( x , t ) = 0 ( 1.1 ) 其中, v 0 v_0

    2024年02月07日
    浏览(44)
  • 理论学习:logits softmax

    在深度学习中, Logits(逻辑值)是指模型的输出层在应用激活函数之前的值 。它通常是一个向量,表示不同类别的得分或概率。在分类问题中,Logits可以被解释为模型对每个类别的置信度或原始预测分数。 模型的输出层通常会应用一个激活函数,例如Softmax函数,将Logits转换

    2024年04月28日
    浏览(43)
  • 【概率论理论】协方差,协方差矩阵理论(机器学习)

      在许多算法中需要求出两个分量间相互关系的信息。协方差就是描述这种相互关联程度的一个特征数。   设 ( X , Y ) (X,Y) ( X , Y ) 是一个二维随机变量,若 E [ ( X − E ( X ) ) ( Y − E ( Y ) ) ] E[(X-E(X))(Y-E(Y))] E [ ( X − E ( X ) ) ( Y − E ( Y ) ) ] 存在,则称此数学期望为 X X X 与

    2024年02月14日
    浏览(46)
  • 机器学习-学习率:从理论到实战,探索学习率的调整策略

    本文全面深入地探讨了机器学习和深度学习中的学习率概念,以及其在模型训练和优化中的关键作用。文章从学习率的基础理论出发,详细介绍了多种高级调整策略,并通过Python和PyTorch代码示例提供了实战经验。 关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构

    2024年02月05日
    浏览(48)
  • 理论U4 集成学习

    传统学习面临的问题:没有任何情况下都最好的机器学习算法 1)背景 通过将多个学习器进行集成,常可获得比单一学习器显著优越的泛化性能,这对弱学习器尤为明显。 弱学习器:准确率仅比随机猜测略高的学习器。 强学习器:准确率高并能在多项式时间内完成的学习器

    2024年01月20日
    浏览(49)
  • 机器学习-方差和偏差理论

    关于机器学习方差和偏差的内容其实很重要,这个方差和偏差可以帮助我们去分析,模型的泛化能力和过拟合的程度。 下面我们先给存储方差和偏差的公式: 注意,下式当中, f ( x ; D ) 表示在数据集 D 上训练出的模型, f − ( x ) 表示无穷多个不同数据集训练出的加权平均模

    2024年02月12日
    浏览(48)
  • 【机器学习】决策树(理论)

    决策树(Decision Tree)是一种分类和回归方法,是基于各种情况发生的所需条件构成决策树,以实现期望最大化的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。它的运行机制非常通俗易懂,因此被誉为机器学习中,最“友好”的算法。下面通过一个

    2024年02月04日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包