【问题标题】:Return a non-resolved promise from a promise从一个承诺中返回一个未解决的承诺
【发布时间】:2016-07-20 16:49:13
【问题描述】:

find 是一个函数,它返回一个解析为一个值的承诺,但也有关于承诺对象本身的数据。一个实际用例是find() 返回一个可以在其他地方使用的 dbQueryObject,而await find() 使用 databaseResults 解析。例如:

function find () {
  var results = new Promise(/* resolves with databaseResults */)
  Object.assign(results, new dbQueryClass)
  return results
}

我可以将find 包装成一个函数来提供这样的帮助,

function findPage (page) {
 return find().skip(page*20).limit(20)
}

并像findPage().select('_id') 一样使用它来获取查询对象或使用await findPage().select('_id') 来获取解析值(返回类似于find() 的内容)。

但是,如果我用这样的承诺包装 find

async function findSomething() {
  var someArgs = await promise1()
  if (someArgs) return find(someArgs)
  return find()
}

如何在findSomething 之外获取find() 本身的值?我需要promise1 来解决,但我需要find() 来解决。 find() 是一个普通对象和一个 thenable,取决于你是否解析它,但解析 findSomething() 将自动解析返回的值。如何返回它以使其无法解决?

我的限制是我不能修改提供 find() 的库以不返回 thenable 对象。

【问题讨论】:

  • 我不明白Promise.resolve 是如何执行查询的。如果它被传递了一个thenable,那么它本质上是一个空操作。无论如何,你的问题到底是什么?
  • 我的问题是,我如何不解决这个 thenable 但在此之前解决 thenables?

标签: javascript mongoose promise async-await


【解决方案1】:

我看不出这里“通常”是什么反模式。您可以在async 函数中returnawait 任何promise、thenable 或plain 值,就像您可以Promise.resolve 它们或从then 回调中返回它们一样。这没有什么不寻常的,就是这样做的。

如果你想明确返回一个承诺,而不是依赖于可同化,你总是可以call .exec() on your mongoose query,它会给你一个“真正的”承诺。

【讨论】:

  • 不,它不会给我一个真正的承诺,它会给我承诺的解决价值。
  • @aaronz:这不太可能,因为这意味着查询将是同步的。你确定不是await ….exec() 给了你履行价值吗?
  • 我已经更新了问题,使其更清晰+更多示例。如果我在一个承诺中return mongooseQuery(),那么等待外部承诺会给我 mongooseQuery 的履行值。我想得到承诺/对象而不是Promise.resolve()ed。
  • 猫鼬查询是同步和异步的。当使用 await/Promise.resolve 调用时,它会返回履行值。当同步调用时,它返回一个 Query 对象(可以在其他地方用于链接)。
  • 啊,感谢您的编辑,现在很清楚您的问题是什么。不幸的是,it's impossible to do this。你会得到的最好的东西是将.then 设置为null,这样你就不再有一个thenable了。但是,对于 Query 对象的承诺对我来说看起来有点奇怪,你必须调用 await (await findSomething()).select('id') 左右。这真的有必要吗,它是最佳的 API 吗?
【解决方案2】:

正如此处https://stackoverflow.com/a/22724984/704894 所述,不可能拥有Promise<Promise<value>>,因为当您在.then 处理程序中返回一个Promise 时,它​​会自动解析(解包)。

您必须使用 Promise<Wrapper<Promise>> 来绕过此限制。

函数式编程人员的旁注:.then 在 Haskell 术语中是 mapflatMap

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-27
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多