【问题标题】:How To Encapsulate I/O and Similar Promises如何封装 I/O 和类似的 Promise
【发布时间】:2019-05-06 14:02:37
【问题描述】:

有许多 I/O 操作——对其他服务器的请求、数据库访问、文件访问——是或应该是承诺。但是,为了封装,可能会发出服务器请求(例如向 Google recaptcha 或 Cloudinary)、数据库调用(例如 PostgreSQL、Mongo、ReDis)或只是读取文件的更高级别的调用。

理想情况下,这些格式应为:

functionCall()
.then(FC1)
.then(FC2)
.catch()

调用的父级不必知道调用的内部结构,或者是随后的 then 或 catch 子句。据我了解,它们应该类似于:

highLevelFuncionCall()
.then(()=>{
   functionCall() //and all its then/catch clauses
}
.then(HLFC1)
.then(HLFC2)
.catch()

但是,它似乎并没有那样工作。无需等待 FC1 和 FC2 即可继续处理 HLFC1,即使需要先处理它们。

如何构造它以使依赖的 Promise 对更高级别的调用者不可见?

谢谢,

大卫

【问题讨论】:

  • then(resolve, reject) 其中 resolve/reject 是一个返回 Promise 的函数。但是() =>´{ functionCall() } 返回 undefined 并立即解决。尝试去除卷曲。
  • 关于范围:不需要解析/拒绝下一个函数的内部。 functionCall 可以看起来像 function functionCall() { return asyncCall().then(()=>Promise.resolve()) }。它将转储任何数据,解析未定义(作为 Promise)并保持链接。
  • 问题是我需要一种方法用于 functionCall 及其 then 子句 FC1 和 FC2,或者它在返回到 highLevelFunctionCall 链之前捕获要调用的错误处理程序。如何将 promise 及其 then 子句保留为原子操作?例如,如果 functionCall 读取数据库,则在 highLevelFunctionCall 处理数据时解析响应,例如验证登录。在 Angular 客户端中,当 then 子句完成时,我们最终会发出消息。我从不喜欢它,也没有看到它在服务器上的 Nodejs 中使用。

标签: javascript node.js ecmascript-6 promise es6-promise


【解决方案1】:

如果我理解正确(基于 cmets),这应该模拟描述的场景:

function getResolved() {
  return new Promise((resolve) => window.setTimeout(resolve, 500, 'ok'));
}

function getRejected() {
  return new Promise((resolve, reject) => window.setTimeout(reject, 500, 'error!'));
}

function progressChain(functionCall) {
  return getResolved() // HLF1
  .then(() => {
    return functionCall() // functionCall with then/catch
    .then(getResolved)
    .then(() => console.log('functionCall resolved'))
    .catch((err) => { // FCC
      console.log('Argh!! functionCall failed!');
      throw err; // rethrow err to chain
    });
  })
  .then(getResolved) // HLF2
  .then((res) => console.log(res)) // HLF3
  .catch((err) => console.log(err)); // HLC
}

// both resolved and rejected scenario (synced)
progressChain(getResolved)
.then(() => progressChain(getRejected))

【讨论】:

  • 我有点困惑。 getResolved 返回一个承诺,并在示例中的任何地方使用。似乎它在每个 then 链的开头都需要一个虚拟 Promise,并将 Promise 和 resolve then 链返回给调用者。 function encap (){ return new Promise((resolve)=>resolve("encap start")) .then((x) => {console.log('encap resolved 1 ' + x); return "encap1"}) .then((x) => {console.log('encap resolved 2 '+ x); return "encap2"}) .catch((err) => { // FCC console.log('Argh!! functionCall failed !'); throw err; // 重新抛出 err 到链 }); }
  • @DavidNJ 这只是一个例子。 getResolved 和 getRejected 是虚拟的 Promise,它们的行为类似于在某处成功或失败的异步调用。它可以只从一个开始,然后只解析 c 的值。关键是您可能应该从内部捕获中重新抛出错误..
  • 另一件事是缺少解析函数的返回值。我不能指导你具体写一篇文章,但是有很多关于 Promises 的文章。只需谷歌它..
  • 我想我已经阅读了几乎所有印在承诺上的东西。尝试了多个库。期望返回一个承诺链应该在返回之前执行该链。它返回第一个 Promise 并独立处理封装的 Promise 链和封装链。所需的行为就像封装链插入到封装链中一样。
  • @DavidNJ 你能在你的问题中添加真正的代码吗?我真的很好奇它是如何发生的,因为 Promise 链的行为是严格给出的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2018-04-10
  • 2017-06-15
  • 1970-01-01
相关资源
最近更新 更多