Почему я не могу использовать Promise.resolve с экземпляром osmosis?

Я пытаюсь понять, почему эти операторы console.log ведут себя по-разному. Я ожидаю, что они будут вести себя так же:

Использование Node 7. Рассмотрим следующие случаи:

<сильный>1. Promise.resolve(объект)

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?

Почему [3] не ведет журнал так же, как [2], учитывая поведение в [1]?

Контекст. Я не думаю, что мои непосредственные практические цели имеют значение для ответа на этот вопрос. Но вот на всякий случай. Я не понимаю, как что-то в самой библиотеке должно повлиять на вывод окончательного примера. Вот документы по этому 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())

person Joseph Fraley    schedule 21.11.2016    source источник
comment
Чего вы на самом деле пытаетесь достичь, заключая объект в Promise.resolve()? Если вы надеетесь, что он будет ждать, пока не будет выполнена какая-то асинхронная операция, обещания работают не так. В этом случае обертывание вашей операции в Promise.resolve() на самом деле вам никак не поможет.   -  person jfriend00    schedule 21.11.2016
comment
Я добавил некоторый контекст выше, если это поможет. Но в случае с этим вопросом я буквально только пытаюсь понять, почему этот console.log печатается пустым.   -  person Joseph Fraley    schedule 21.11.2016
comment
stackoverflow.com/questions/22519784/   -  person Benjamin Gruenbaum    schedule 21.11.2016
comment
@ Бенджамин Грюнбаум, но почему я могу напрямую console.log создать новый экземпляр, но никогда не увижу экземпляр, переданный через Promise.resolve? Это не вопрос обратных вызовов. У меня есть прямой, немедленный, синхронный доступ к экземпляру new osmosis вне контекста Promise.resolve.   -  person Joseph Fraley    schedule 21.11.2016
comment
На всякий случай... перехватите вызов osmosis... может быть, osmosis.get выдает исключение, поэтому не достигает пункта then()   -  person Manu    schedule 21.11.2016
comment
@Manu, это больше не проблема с node. Он будет регистрировать необработанные отказы.   -  person Benjamin Gruenbaum    schedule 21.11.2016


Ответы (1)


Документация ужасна и использует довольно нетрадиционные методы. new osmosis.get(url) возвращает не экземпляр Osmosis, а Command один. И у них есть метод then.

Когда вы передаете что-то в Promise.resolve, оно проверяется на предмет того, является ли оно затем или нет, и если оно выглядит как обещание, оно пытался быть ассимилирован: обратный вызов передается в метод then, который разрешает новое обещание.

Поэтому, когда вы выполняете Promise.resolve(new osmosis.get(url)), вы получаете неразрешенное обещание, которое будет выполняться при вызове обратного вызова then (что происходит, когда вы запускаете команду). В вашем случае - никогда.

Решение вашей конкретной проблемы состоит в том, чтобы вообще не использовать обещания (поскольку вы не делаете ничего асинхронного):

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

но вам, вероятно, также следует сообщить об ошибке, из-за которой Commands выглядят как промисы с возможностью правильного выбора, что ломает много вещей в ES6.

person Bergi    schedule 21.11.2016
comment
Да, ошибка с утиным набором текста — это то, чего я не видел. Вы правы, я не могу просто передать экземпляр через серию функций, но это выглядит как мусор, и я надеялся избежать этого. Это правда, что на самом деле я не делаю ничего асинхронного, но цепочка обещаний естественным образом описывает то, что интуитивно кажется происходящим при запуске скребка (просто без его фактического запуска). Большое спасибо! (да, эти документы дрек) - person Joseph Fraley; 22.11.2016
comment
Для доказательства этот ответ правильный: const x = new osmosis(); х.затем = ноль; Promise.resolve(x).then(console.log) // все работает - person Joseph Fraley; 22.11.2016