稍后解决承诺

2024-06-20

我想构建一个 Promise,但将解决方案推迟到以后。下面的代码创建了一个承诺,但它立即得到解决。我如何控制承诺何时被评估?

var p = new Promise((resolve, reject) => {
        resolve(1);
    })
    .then((p1) => {
        console.log(p1 + 1);
    });

更新:澄清一下,想要将承诺的声明与其执行分开的原因是添加then基于一些参数动态回调。


你可以通过resolve and reject到您想要使用的任何异步函数。并且这样的函数可以在完成其工作时调用它。这是一个在 Node 中运行的示例。如果你运行这个,它将执行ls -l在您当前的目录中。这execSomething函数只接受回调并且promiseToExec函数通过了resolve, reject回调到execSomething而不是立即打电话给他们中的任何一个。

const childProcess = require("child_process");

function execSomething(command, options, onSuccess, onError) {
  childProcess.exec(command, options, (err, stdout, stderr) => {
    if (err) {
      onError(err);
    }
    onSuccess(stdout, stderr);
  });
}

function promiseToExec(command, options) {
  return new Promise((resolve, reject) => {
      execSomething(command, options, resolve, reject);
  });
}

promiseToExec("ls -l").then(console.log.bind(console));

卡兹劳斯基斯 https://stackoverflow.com/a/39649159/1906307建议这样做:

var resolve;
var promise = new Promise(function(fulfill) {
  resolve = fulfill;
});

不要这样做!.

当您传递给的回调中发生异常时new Promise,promise 的规范是这样的,异常将自动转换为promise 拒绝。所以如果有什么事情的话throw Error...在回调中你会得到自动转换。

如果您保存resolve回调并将您的逻辑移至您传递给的回调之外new Promise,那么您就不会获得此自动转换。回调之外抛出的异常将仅在堆栈中向上传递而不被转换为承诺拒绝。这很糟糕,因为它需要您的函数的用户才能使用.catch抓住被拒绝的承诺and try...catch对于抛出的异常。这是一种糟糕的设计实践。

这是说明问题的代码:

// This is how things should be done.
function makeGoodPromise(num) {
  return new Promise((resolve) => {
    if (num < 0) {
      throw new Error("negative num");
    }
    resolve(num);
  });
}

// This is a bad approach because it will sometimes result in synchronous
// exceptions.
function makeBadPromise(num) {
  let resolve;
  const p = new Promise((fullfil) => {
    resolve = fullfil;
  });

  if (num < 0) {
    throw new Error("negative num");
  }
  resolve(num);

  return p;
}

// Shoring up the bad approach with a try... catch clause. This illustrates what
// you need to do convert the exception into a rejection. However, why deal with the
// additional scaffolding when you can just take the simpler approach of not
// leaking the callbacks??
function makeBadPromise2(num) {
  let resolve, reject;
  const p = new Promise((fullfil, deny) => {
    resolve = fullfil;
    reject = deny;
  });

  try {
    if (num < 0) {
      throw new Error("negative num");
    }
    resolve(num);
  }
  catch (e) {
    reject(e);
  }

  return p;
}


makeGoodPromise(-1).catch(() => console.log("caught the good one!"));

try  {
  makeBadPromise(-1).catch(() => console.log("caught the bad one!"));
}
catch(e) {
  console.log("Oops! Synchronous exception: ", e);
}

makeBadPromise2(-1).catch(() => console.log("caught the bad2 one!"));

当我在 Node 中执行它时,这是输出:

Oops! Synchronous exception:  Error: negative num
    at makeBadPromise (/tmp/t12/test2.js:17:11)
    at Object.<anonymous> (/tmp/t12/test2.js:48:3)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
caught the good one!
caught the bad2 one!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

稍后解决承诺 的相关文章

随机推荐

  • 将 Word 文档另存为图像

    我正在使用下面的代码将 Word 文档转换为图像文件 但是图片显得太大 内容不适合 有没有办法渲染图片或将图片保存到合适的尺寸 private void btnConvert Click object sender EventArgs e
  • 在 iFrame 内维护会话状态

    不确定我是否疯了 但我在 iFrame 内的会话状态遇到问题 它是一个域在另一个域中的简单设置 我不需要跨域共享任何内容 我想做的就是将一个网站嵌入到另一个网站中 并且我希望该嵌入网站能够使用 cookie 会话状态登录 编辑 更新 等 为
  • META-INF/服务应该在 sbt 中的哪里

    META INF 目录应该放在哪里 以便 sbt 获取自定义配置 我在尝试使用 ServiceLoader 时遇到了这个问题 并且我试图在 META INF services 中创建自定义服务 如果您将 META INF 文件夹放在 src
  • 非 Spring 托管类中 DI 的编译时编织

    我想为标记为的类配置编译时编织 Configurable注释能够将 spring 依赖项注入到初始化的类中new操作员 我不想使用加载时编织 因为我无权访问应用程序服务器的运行脚本 因此无法修改它 另外 我希望能够在测试中使用此类 我的意思
  • Typescript导入别名+桶文件

    我最近花了很多时间 因为 Angular ngrx typescript 生态系统中某些事物的特定行为 并且我无法识别可能的根本原因 场景 我已经构建了一些效果 并将它们导出到桶文件中 index ts import MyEffects f
  • 尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

    我尝试过使用 sigaction 和 ctypes 设置信号处理程序 我知道它可以与python中的信号模块一起使用 但我想尝试学习 当我向该进程发送 SIGTERM 时 但它没有调用我设置的处理程序 只打印 终止 为什么它不调用处理程序
  • Electron - 为什么在关闭事件时将 BrowserWindow 实例设置为 null

    The 电子文档 https electronjs org docs api browser window 提供以下代码示例来创建新窗口 const BrowserWindow require electron let win new Br
  • Github 页面 - 禁用除单个站点之外的所有站点的自定义域重定向?

    I ve been using github pages since a long time and use the custom domain redirection feature to redirect my user website
  • 如何更改特定区域的工作表的 DragGesture?

    如果我有一个打开工作表的按钮 Button action show true label Text Open sheet isPresented show Text Sheet view 整张纸是 可移动的 有一个DragGesture 有
  • 如何在 Ruby 中重写 require ?

    我需要覆盖require来自 Ruby 文件 这是我的 start rb 应用程序入口点 所必需的 rubygems在此之前加载 位于 start rb 中 我尝试的所有操作都出现了堆栈溢出错误 正确的做法是什么 一般来说 如果你想修补一些
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • 如何在机器人框架中的两条消息之间设置延迟 - Node.js

    我正在开发一个机器人 它使用 botbuilder JS V4 使用 Direct Line 连接到我们的客户端应用程序 由于某些原因 消息以错误的顺序发送给机器人 例如 用户 你好 机器人 我能帮你什么忙吗 机器人 嗨 我是机器人 作为解
  • node.js 本身还是 nginx 前端来提供静态文件?

    是否有更快的基准或比较 将 nginx 放在节点前面并让它直接提供静态文件或仅使用节点并使用它提供静态文件 nginx 解决方案似乎对我来说更易于管理 有什么想法吗 我不得不不同意这里的答案 虽然 Node 可以做得很好 但如果配置正确 n
  • Angular 2+ 安全性;保护服务器上的延迟加载模块

    我有一个 Angular 2 应用程序 用户可以在其中输入个人数据 该数据在应用程序的另一部分进行分析 该部分仅适用于具有特定权限的人员 问题是我们不想让未经授权的人知道how我们正在分析这些数据 因此 如果他们能够在应用程序中查看模板 那
  • 获取 FTP 服务器上的文件大小并将其放在标签上

    我正在尝试获取托管在FTP服务器并将其放入Label而 BackgroundWorker 在后台工作 我在用着 Try 来获取该值 但是该值在第一次尝试时被捕获 下载后 如果我按尝试再次获取它 那么它就可以工作 Note 第一次尝试时进度条
  • glibc 堆一致性检查

    根据2008年的帖子 我现在找不到 glibc 堆检查 http www gnu org s libc manual html node Heap Consistency Checking html在多线程环境中不起作用 现在还是2010年
  • 叠加 SKScene 未显示

    我正在尝试将 SKScene 覆盖在 SCNScene 上 当我在模拟器和 iPhone6 上运行我的应用程序时 overlayScene SKScene 按预期显示 但是当我尝试在 iPhone5 上运行它 尝试了 2 个不同的设备 时
  • 如何将 ascii 值列表转换为 python 中的字符串?

    我在 Python 程序中有一个列表 其中包含一系列数字 这些数字本身就是 ASCII 值 如何将其转换为可以在屏幕上回显的 常规 字符串 您可能正在寻找 chr gt gt gt L 104 101 108 108 111 44 32 1
  • Firebase ref.removeAllObservers() 是否也会递归删除子观察者?

    我看到了一些与此相关的问题 但没有一个真正证实了我的疑问 If I removeAllObservers 在父节点上 这是否也会递归地删除可能已附加在所有子节点和子节点的子节点等处的所有其他观察者 递归地 API 文档为removeAllO
  • 稍后解决承诺

    我想构建一个 Promise 但将解决方案推迟到以后 下面的代码创建了一个承诺 但它立即得到解决 我如何控制承诺何时被评估 var p new Promise resolve reject gt resolve 1 then p1 gt c