Why can't I use Promise.resolve with an osmosis instance?

柔情痞子 提交于 2020-01-04 01:52:50

问题


I am trying to understand why these console.log statements behave differently. I expect them to behave the same:

Using Node 7. Consider the following cases:

1. Promise.resolve(object)

Promise.resolve handles objects as I'd expect:

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

2. Directly console.log a class instance from a library.

If I store an Osmosis instance I can console.log it:

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(class instance)

But if I try to resolve an Osmosis instance I don't see parity:

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

What's going on here? Am I misunderstanding something about Promise.resolve()...? Or console.log?

Why doesn't [3] log the same as [2], given the behavior in [1]?

Context: I don't think my immediate practical goals matter to answering this question. But here you go just in case. I don't see how anything about the library itself should affect the output of the final example. Here's the docs on that new osmosis.get() though: http://rchipka.github.io/node-osmosis/Osmosis.html#toc1__anchor

new osmosis.get(url) doesn't perform an async http request. It instantiates an instance of the scraper, which can be built up with a set of declarative instructions and told to "run" at some arbitrary later time.

I want to be able to build this set of instructions in a promise chain for several reasons.

The main one is that it would be the easiest way to break up the instruction definitions into different functions that are easier to test and understand. e.g. instead of osmosis.get(url).set({some stuff}).find(@something), I'd like to:

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())

回答1:


The documentation is horrible and uses techniques that are rather unconventional. What new osmosis.get(url) returns is not an Osmosis instance but a Command one. And those do have a then method.

When you pass something to Promise.resolve, it is tested for being a thenable or not, and if it looks like a promise it is tried to be assimilated: a callback is passed into the then method which will resolve the new promise.

So when you do Promise.resolve(new osmosis.get(url)), you get back an unresolved promise that will fulfill when the then callback is called (which happens when you run the command). In your case, it never does.

The solution to your particular problem is not to use promises at all (since you're not doing anything asynchronous):

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

but you probably should also report a bug that Commands look like promises with being properly thenable, which breaks a lot of things in ES6.



来源:https://stackoverflow.com/questions/40716155/why-cant-i-use-promise-resolve-with-an-osmosis-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!