Promises: JavaScript异步编程的救星

6,585次阅读
没有评论

共计 1501 个字符,预计需要花费 4 分钟才能阅读完成。

Promises(承诺)是 JavaScript 中处理异步操作的一种机制,它提供了一种更优雅和可读性更高的方式来处理异步代码。Promises 的实现原理基于一种称为 ”Promise/A+” 规范的约定,该规范定义了 Promises 的行为和接口。

Promises 的实现原理是什么?

Promises: JavaScript 异步编程的救星

Promises 的实现原理可以通过以下 4 步概括:

  1. Promise 有 3 种状态:pending、fulfilled 和 rejected。初始状态为 pending。
  2. Promise 实例包含一个 then 方法,then 方法接受两个参数:onFulfilled 和 onRejected, 分别为 promise 成功或失败的回调。
  3. Promise 有一个内部属性[[PromiseState]], 初始值为 pending。内部又有一个属性[[PromiseResult]], 初始值为 undefined。
  4. Promise 的状态只能从 pending 到 fulfilled 或 rejected, 状态一旦改变就不能再变。fulfilled 和 rejected 状态都会触发 then 里的回调。

当我们 new 一个 Promise 时, 会传入一个执行器 executor, 执行器会立即执行。在执行器中我们可以处理异步任务, 比如发送 ajax 请求, 一旦异步任务执行结束, 就可以决定是 resolve(成功)还是 reject(失败)这个 promise。

如果执行 resolve, 那么将 [[PromiseState]] 设为 fulfilled,[[PromiseResult]]设为传入的值。执行 onFulfilled 回调。

如果执行 reject, 那么将 [[PromiseState]] 设为 rejected,[[PromiseResult]]设为传入的 reason。执行 onRejected 回调。

这样通过状态和结果的改变, 来触发 then 里不同的回调, 从而实现异步流程的控制。

Promise 就是通过状态改变来触发回调的, 这也是它实现异步编程的基石。

如果在 Promise 的执行器函数 (executor) 中不调用 resolve 或 reject,会怎么样?

如果在 Promise 的执行器函数 (executor) 中不调用 resolve 或 reject, 通常会导致两个结果:

  • Promise 对象的状态永远保持 pending

Promise 对象代表一个异步操作, 它的最终状态应该在某个时刻确定下来(fulfilled 或 rejected)。如果 executor 函数中不调用 resolve 或 reject,Promise 的状态就无法得以确定, 会永远处于 pending 状态。

  • then 方法指定的回调函数不会被调用

then 方法注册的回调函只有在 Promise 状态确定后才会被调用, 如果状态一直是 pending, 那么 then 方法的回调函数就永远不会被执行。

所以, 如果在 executor 函数中不调用 resolve 或 reject, 就是一个错误的实现, 违反了 Promise/A+ 规范。

正确的做法是, 在 executor 函数中, 无论异步任务是否成功, 都需要在最后调用 resolve 或者 reject, 将 Promise 的状态确定下来, 以便触发 then 方法注册的回调。通常 like 这样:

new Promise((resolve, reject) => {if(成功) {resolve(value); } else {reject(error); } })

所以, 不调用 resolve/reject, 将导致 Promise 永远 pending, 然后注册的回调函数也就不会执行。这违反 Promise 的设计初衷, 应该避免这样使用。

原文地址: Promises: JavaScript 异步编程的救星

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-19发表,共计1501字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)