首页 > web前端 > js教程 > 正文

优雅地结合 Async/Await 与可取消的 Bluebird Promise

霞舞
发布: 2025-10-08 10:30:13
原创
365人浏览过

优雅地结合 async/await 与可取消的 bluebird promise

本文旨在解决在使用 Bluebird Promise 实现可取消的异步操作时,async/await 导致的程序卡死问题。我们将探讨如何利用 ES6 内置的 AbortController 来实现 Promise 的取消,并确保程序在取消后能够正常执行后续流程,避免代码阻塞。通过示例代码,我们将展示如何将 AbortController 集成到你的异步函数中,并正确处理取消事件,从而构建更加健壮和可控的异步代码。

在使用 Bluebird 的可取消 Promise 时,结合 async/await 可能会遇到一些问题,尤其是在 Promise 被取消的情况下,程序可能会卡在 await 语句处,导致后续代码无法执行。 这主要是因为取消操作没有正确地通知 await 表达式,使得它一直等待 Promise 的 resolve 或 reject。

解决这个问题的关键在于使用 ES6 内置的 AbortController。AbortController 提供了一种标准的方式来取消异步操作,并且可以与 Promise 结合使用。

使用 AbortController 取消 Promise

以下是一个使用 AbortController 实现可取消 Promise 的示例:

SpeakingPass-打造你的专属雅思口语语料
SpeakingPass-打造你的专属雅思口语语料

使用chatGPT帮你快速备考雅思口语,提升分数

SpeakingPass-打造你的专属雅思口语语料 25
查看详情 SpeakingPass-打造你的专属雅思口语语料
let myP = (signal) =>
  new Promise((resolve, reject) => {
    const tm = setTimeout(function () {
      console.log("before resolve");
      resolve("Success!"); // Yay! Everything went well!
    }, 2500);

    // signal.onabort = () => { // 旧写法,不推荐
    signal.addEventListener('abort', () => {
      console.log('aborted');
      clearTimeout(tm);
      reject(new Error('Promise Aborted')); // 建议 reject,方便错误处理
      // resolve(); // 也可以 resolve,取决于业务需求
    });
  });

const run = async () => {
  console.log("Start");

  const controller = new AbortController();
  const signal = controller.signal;
  const prm = myP(signal);

  setTimeout(() => controller.abort(), 1000);

  try {
    await prm;
    console.log("After await prm");
  } catch (e) {
    console.error("Caught error:", e);
  } finally {
    console.log("Finished");
  }
};

run();
登录后复制

代码解释:

  1. AbortController 的创建: 首先,我们创建一个 AbortController 实例。
  2. signal 的传递: 将 AbortController 的 signal 传递给 myP 函数。signal 对象用于监听取消事件。
  3. addEventListener('abort', ...): 在 myP 函数内部,我们使用 signal.addEventListener('abort', ...) 监听 abort 事件。 当 AbortController 调用 abort() 方法时,该事件会被触发。
  4. 取消处理: 在 abort 事件处理函数中,我们执行取消操作,包括清除定时器 clearTimeout(tm),并调用 reject(new Error('Promise Aborted')) 来拒绝 Promise。 也可以根据业务需求选择 resolve()。 建议使用 reject,因为这样可以在 catch 块中处理取消错误。
  5. controller.abort() 的调用: 在 run 函数中,我们使用 setTimeout 在 1 秒后调用 controller.abort(),模拟取消操作。
  6. 错误处理: 使用 try...catch 块来捕获可能发生的错误,包括取消导致的错误。

注意事项:

  • reject vs resolve: 当 Promise 被取消时,应该选择 reject 还是 resolve 取决于你的业务逻辑。 如果取消被视为一种错误情况,则应该 reject Promise。 如果取消只是中断了操作,并且不需要进一步处理,则可以 resolve Promise。
  • 资源清理: 在 abort 事件处理函数中,务必清理所有已分配的资源,例如定时器、网络连接等,以避免内存泄漏。
  • signal.onabort vs signal.addEventListener('abort', ...): 建议使用 addEventListener,因为它允许你注册多个取消处理函数。 避免使用 signal.onabort = ...,因为它只能注册一个处理函数。
  • 多个 Promise 的取消: 可以使用同一个 AbortController 的 signal 来取消多个 Promise。 这在需要同时取消多个相关操作时非常有用。

总结

AbortController 提供了一种简洁而强大的方式来取消异步操作,并且可以与 async/await 和 Promise 无缝集成。 通过使用 AbortController,你可以构建更加健壮和可控的异步代码,避免程序卡死,并有效地管理资源。 记得在取消处理函数中清理资源并根据业务需求选择 reject 或 resolve Promise。

以上就是优雅地结合 Async/Await 与可取消的 Bluebird Promise的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号