LINUX.ORG.RU

Вопров по Promise

 , ,


0

1

Всем привет.

Хочу запилить корректную обработку ошибок.

С сервера приходит ответ в виде:

1) В случае успеха:

success: true, result: my_data

2) В случае какй-либо ошибки:

success: false, error: {code: ..., message: ...

Вопрос корректно ли проверять success и, в случае неуспеха, реджектить обещание:

if (resp.success) {	resolve(resp.result); }
else { reject(resp.error); }

Или в reject попадают исключения на уровне зпроса (http-ошибки и прочее)?


.reject() означает, что пропустятся все последующие .then() до .catch() (или до then со вторым параметром)

Тот вариант заворачивания в промис, что ты привел - вполне корректный.

Ты только учти, что промисы очень активно хавают эксепшены. Если будешь из них колбеки пытаться дернуть - оборачивай в nextTick() или что-то подобное.

Vit ★★★★★ ()

да, все правильно у тебя. Кстати, тут предыдущий оратор высказывался там что то про хаванье эксепшнов, ты его не слушай, это местный клоун. Он может реально только циклы писать, а в основном слышит звон, да не знает где он.

Или в reject попадают исключения на уровне зпроса (http-ошибки и прочее)?

ты можешь принудительно туда их отправить, например

xhr = ...
xhr.onreadystatechange = function(){
 ...
 if (xhr.status != 200) regect(xhr.status)
}
сами нет, не отправляются

filequest ()

Да, про так называемое хавнье эксепшнов. Я понял, что клоуны имеют под этим в виду. промисом нужно оборачивать толькор асинхронный код, синхронный оборачивать не нужно (в тч не имеет смысла) и чревато, да. Из него может действительно потеряться выброшенное исключение.

filequest ()
Ответ на: комментарий от Vit

всмысле «хавают»? И вообще законно ли использваоть nextTick()? Код же автоматом нетестируемй делается

Nicholass ★★★ ()
Ответ на: комментарий от Nicholass

В смысле там везде внутри try/catch, и ты внезапно можешь словить совершенно не то что ждал.

Ты можешь считать, что дергаешь асинхронный код, но где-то там внутри будет например деление на ноль. И это улетит не дальше в колбек, как хотелось бы, а может прилететь обратно в скоп промиса, и там погибнуть. Или повторно что-нибудь не то дернуть дальше по цепочке, еще веселее.

Поэтому лучше отвязаться от промиса. Можно через setTimeout(xx, 0), но там задержки большие, лучше через nextTick(). Тогда эксепшен улетит в глобальный контекст, и его можно словить черех unhandledException. Это конечно слегка тухловатая тема, но всяко лучше чем с концами просрать ошибку и потом пытаться понять в чем дело.

В общем, промисы с колбеками лучше не мешать, или делать это очень аккуратно если иначе совсем никак.

Vit ★★★★★ ()
Ответ на: комментарий от Nicholass

Код же автоматом нетестируемй делается

да нет, он тестируем, просто надо туда засовывать анонимный коллбек

onsuccess = onerror =  function(x){console.log(x)}


new Promise(function(resolve, reject){
   process.nextTick(function(){
      try{
         foo
         resolve(1)
      }catch(e){
         reject(e)
      }
   })
})
 .then(onsuccess)
 .catch(onerror)

// [ReferenceError: foo is not defined]
это уродство идет из-за лексической области видимости. Пользуясь случаем, передаю привет главному дрочеру на замыкания, Hello, Dug, how are you, fuckin' faggot?

filequest ()

Зачем нужен success, если можно детектить по наличию error или отсутствию result

anonymous ()
Ответ на: комментарий от filequest

надо туда засовывать анонимный коллбек

собственно, не обязательно анонимный, но определенный в области видимости коллбека промиса. Либо, как (слегка извращенный) вариант, пробрасывать ссылки на текущий resolve и reject во временный неймспейс.

filequest ()
Ответ на: комментарий от Nicholass

Естественно ловятся. Речь о том, что ты можешь словить совершенно не то что хотел. Например, ты хочешь развернуть промис на колбеки и пишешь в конце цепочки:

.then(res => callback(null, res), err => callback(err)


И вроде как ты передал управление правильно, и ни каких эксепшенов в колбеках быть не должно. Но когда случится - станет грустно.

Либо ты пишешь

.then(res => callback(null, res))
.catch(err => callback(err)


У тебя вызывается колбек, там эксепшен, и потом колбек еще раз. Тоже весело.

Красивых выходов особо нет. Либо заруливать такие ошибки на монитор пропущеных эксепшенов (если библиотека типа blueburd позволяет), либо фигачить в глобальный неймспейс.

Vit ★★★★★ ()

Всем отметившимся в треде, особенно Vit... Где весь этот shit описан на пальцах, не отвлекаясь на фреймворки, hello world и снежинки??? И почему в любом другом ЯП проще?

Shadow ★★★★★ ()
Последнее исправление: Shadow (всего исправлений: 1)
Ответ на: комментарий от Shadow

Уточни вопрос, про какой именно shit тебе надо.

Vit ★★★★★ ()
Ответ на: комментарий от Vit

«ты можешь словить совершенно не то что хотел» - best pratices, чтобы так не получалось.

Shadow ★★★★★ ()
Ответ на: комментарий от Shadow

нигде. В спецификации это все есть, но там не на пальцах. А фреймверки тут вообще не при чем. А в том, что реализация промисов в JS кривая — ты прав. Виной тому, в первую очередь, фокусировка на лексические замыкания и отход от ООП-парадигмы. К примеру, это непосредственно касается вопроса, почему ты не можешь тупо вставить коллбек и поймать из него ошибку? Ответ прост — коллбек лексически связан со своим окружением, он не видит никакой resolve/reject области видимости, в котрой сеттится. Это можно обойти, конечно, есть способы, но проще было не делать говно на уровне реализации.

filequest ()
Ответ на: комментарий от Shadow

Ну что нельзя оставлять цепочки промисов болтаться без .catch(), вроде везде пишут. Про колбеки не знаю - обычная логика. Из той же серии, что при имплементации `once(fn)` флажок надо ставить до вызова fn а не после :).

Vit ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.