前端JavaScript基础训练系列一百六十一:回调未调用

本文详细阐述了Promise的运作原理,包括如何处理完成和拒绝回调,JavaScript错误的处理,以及超时机制。此外,还讨论了回调调用次数的保证和参数传递的规则,强调了Promise如何确保一致性并利用JavaScript闭包特性。
摘要由CSDN通过智能技术生成

首先,没有任何东西(甚至 JavaScript 错误)能阻止 Promise 向你通知它的决议(如果它 决议了的话)。如果你对一个 Promise 注册了一个完成回调和一个拒绝回调,那么 Promise 在决议时总是会调用其中的一个。
当然,如果你的回调函数本身包含 JavaScript 错误,那可能就会看不到你期望的结果,但 实际上回调还是被调用了。后面我们会介绍如何在回调出错时得到通知,因为就连这些错 误也不会被吞掉。
但是,如果 Promise 本身永远不被决议呢?即使这样,Promise 也提供了解决方案,其使用 了一种称为竞态的高级抽象机制:

// 用于超时一个Promise的工具 function timeoutPromise(delay) {
         return new Promise( function(resolve,reject){
             setTimeout( function(){
                 reject( "Timeout!" );
             }, delay );
} ); }
// 设置foo()超时 Promise.race( [
    foo(),
    timeoutPromise( 3000 )
]) .then(
function(){
// foo(..)及时完成!
},
// 试着开始foo() // 给它3秒钟
function(err){
// 或者foo()被拒绝,或者只是没能按时完成 // 查看err来了解是哪种情况
} );

关于这个 Promise 超时模式还有更多细节需要考量,后面我们会深入讨论。 很重要的一点是,我们可以保证一个 foo() 有一个输出信号,防止其永久挂住程序。

调用次数过少或过多

根据定义,回调被调用的正确次数应该是 1。“过少”的情况就是调用 0 次,和前面解释过
的“未被”调用是同一种情况。
“过多”的情况很容易解释。Promise 的定义方式使得它只能被决议一次。如果出于某种 原因,Promise 创建代码试图调用 resolve(…) 或 reject(…) 多次,或者试图两者都调用, 那么这个 Promise 将只会接受第一次决议,并默默地忽略任何后续调用。
由于 Promise 只能被决议一次,所以任何通过 then(…) 注册的(每个)回调就只会被调 用一次。
当然,如果你把同一个回调注册了不止一次(比如p.then(f); p.then(f)😉,那它被调用 的次数就会和注册次数相同。响应函数只会被调用一次,但这个保证并不能预防你搬起石 头砸自己的脚。

未能传递参数 / 环境值 Promise 至多只能有一个决议值(完成或拒绝)。

如果你没有用任何值显式决议,那么这个值就是 undefined,这是 JavaScript 常见的处理方 式。但不管这个值是什么,无论当前或未来,它都会被传给所有注册的(且适当的完成或 拒绝)回调。

还有一点需要清楚:如果使用多个参数调用 resovle(…) 或者 reject(…),第一个参数之 后的所有参数都会被默默忽略。这看起来似乎违背了我们前面介绍的保证,但实际上并没 有,因为这是对 Promise 机制的无效使用。对于这组 API 的其他无效使用(比如多次重复 调用 resolve(…)),也是类似的保护处理,所以这里的 Promise 行为是一致的(如果不是 有点令人沮丧的话)。

如果要传递多个值,你就必须要把它们封装在单个值中传递,比如通过一个数组或对象。 对环境来说,JavaScript 中的函数总是保持其定义所在的作用域的闭包,所以它们当然可以继续访问你提供的 环境状态。当然,对于只用回调的设计也是这样,因此这并不是 Promise 特有的优点—— 但不管怎样,这仍是我们可以依靠的一个保证。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值