【问题标题】:Why can't I use Promise.resolve with an osmosis instance?为什么我不能将 Promise.resolve 与 osmosis 实例一起使用?
【发布时间】:2017-04-04 14:39:58
【问题描述】:

我试图理解为什么这些console.log 语句的行为不同。我希望它们表现相同:

使用节点 7。考虑以下情况:

1. Promise.resolve(object)

Promise.resolve 按我的预期处理对象:

Promise.resolve({ a: `hello` }).then(console.log) // { a:'hello' }

2。直接console.log 库中的类实例。

如果我存储一个 Osmosis 实例,我可以 console.log 它:

const osmosis = require(`osmosis`)
console.log(new osmosis.get(url)) 
/* { prev:                                                                                                                                                                   
     { instance: Osmosis:1,                                                                                                                                                 
     name: 'get',                                                                                                                                                         
     args: [ 'http://www.google.com', ,  ],                                                                                                                               
     getURL: [Function: getURLArg],                                                                                                                                       
     url: 'http://www.google.com',                                                                                                                                        
     params: undefined,                                                                                                                                                   
     cb: [Function: Get],                                                                                                                                                 
     next: [Circular] } }
*/

3. Promise.resolve(类实例)

但如果我尝试解析 Osmosis 实例,我看不到奇偶校验:

Promise.resolve(new osmosis.get(url)).then(console.log) // nothing

这里发生了什么?我对Promise.resolve()...有什么误解吗?还是console.log

考虑到 [1] 中的行为,为什么 [3] 的日志记录与 [2] 不同?

背景:我认为我的直接实际目标对于回答这个问题并不重要。但在这里你去以防万一。我看不出库本身会如何影响最终示例的输出。这是new osmosis.get() 上的文档:http://rchipka.github.io/node-osmosis/Osmosis.html#toc1__anchor

new osmosis.get(url) 不执行异步 http 请求。它实例化了一个刮板实例,该实例可以使用一组声明性指令构建,并被告知在以后的任意时间“运行”。

出于几个原因,我希望能够在承诺链中构建这组指令。

主要的一个是将指令定义分解为更易于测试和理解的不同功能的最简单方法。例如而不是osmosis.get(url).set({some stuff}).find(@something),我想:

function defineSearch(instance){
  return instance.set({some stuff})
}

function definePath(instance) {
  return instance.find(@something)
}

Promise.resolve(new osmosis.get(url))
  .then(defineSearch)
  .then(definePath)
  .then(instance => instance.run())

【问题讨论】:

  • 通过在Promise.resolve() 中包装一个对象,您实际上想完成什么?如果您希望它会等到某些异步操作完成,那不是 Promise 的工作方式。在这种情况下,将您的操作包装在 Promise.resolve() 中并不能真正帮助您。
  • 如果有帮助,我在上面添加了一些上下文。但在这个问题的情况下,我实际上只是想了解为什么 console.log 打印为空。
  • @Benjamin Gruenbaum 但是为什么我可以直接console.log 一个新实例,却永远​​看不到通过Promise.resolve 传递的实例?这不是回调的问题。我对Promise.resolve 上下文之外的new osmosis 实例具有直接、即时、同步的访问权限。
  • 以防万一... catch 调用osmosis... 可能osmosis.get 正在引发异常,因此无法到达then() 子句跨度>

标签: node.js promise es6-promise console.log


【解决方案1】:

文档很糟糕,并且使用了非常规的技术。 new osmosis.get(url) 返回的不是Osmosis 实例,而是Command 实例。而那些确实有then method

当你向Promise.resolve传递一些东西时,它会被测试是否是thenable,如果它看起来像一个promise,它会被尝试被同化:一个回调被传递给then方法,它将解决新的承诺。

因此,当您执行Promise.resolve(new osmosis.get(url)) 时,您会返回一个未解决的承诺,该承诺将在调用then 回调时实现(当您运行命令时会发生这种情况)。在你的情况下,它永远不会。

解决您的特定问题的方法是根本不使用承诺(因为您没有做任何异步操作):

definePath(defineSearch(new osmosis.get(url))).run())

但您可能还应该报告一个错误,即Commands 看起来像 Promise 并且可以正常使用,这会破坏 ES6 中的很多东西。

【讨论】:

  • 是的,鸭子打字错误是我没有看到的。没错,我不能只通过一系列函数传递实例,但它看起来像垃圾,我希望避免它。确实,我实际上并没有做任何异步的事情,但是 promise 链自然地描述了当刮板启动时它直观地似乎正在发生的事情(只是没有实际启动它)。非常感谢! (是的,那些文档是 drek)
  • 为了证明这个答案是正确的: const x = new osmosis(); x.then = null; Promise.resolve(x).then(console.log) // 一切正常
猜你喜欢
  • 2020-08-26
  • 2013-07-02
  • 2015-11-08
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 2011-06-05
  • 2013-08-15
相关资源
最近更新 更多