Как отлаживать обещания javascript?
Я пытаюсь понять, как отлаживать асинхронный код, основанный на обещаниях. Под обещаниями я подразумеваю обещания на основе ECMAScript 6, а под отладкой я имею в виду использование встроенного отладчика chrome или firefox.
что у меня возникли проблемы с - это то, что при возникновении ошибки я не могу получить трассировку стека независимо от того, как я "отклоняю" его.
Я попытался это:
console.log(new Error('Error occured'));
throw new Error('Throwing an Error');
return new Error('Error returned by the onRejected function');
reject(new Error('Pass Error to the reject function'));
но ни один из них не возвращает фактическую ошибку в коде или стеке след.
Итак, мой вопрос - Как правильно отлаживать обещания javascript?
6 ответов:
Это отличная тема для обсуждения, печальные новости это на самом деле довольно трудно с родными обещаниями.
отладка raw ES6 обещает в Chrome ужасно. Это потому, что они будут молча подавлять ошибки, и всякий раз, когда вы опускаете улов, он не даст вам никаких признаков того, что обещание не удалось.обновление: Chrome теперь регистрирует необработанные отклонения (см. Эту ссылку для how)Promise.resolve("foo").then(function(){ throw new Error("You will never see this");// silent failure });
в Firefox все немного лучше, так как они выполните необработанное обнаружение отклонения-однако, это все еще flakey, и если вы назначили обещание в любом месте, оно не будет работать.
Итак, что же можно сделать?
включить птица - это надмножество обещаний ES6, и вы можете поменять его прямо внутри, у него есть более богатый API, он быстрее и у него есть удивительные трассировки стека. Он построен с учетом отладки и включает в себя большие средства обработки ошибок.
как только вы включили Bluebird, звоните:
Promise.longStackTraces();
который замедлит его немного (это все равно будет очень быстро) и даст вам удивительные сообщения об ошибках. Например:
Promise.resolve().then(function outer() { return Promise.resolve().then(function inner() { return Promise.resolve().then(function evenMoreInner() { a.b.c.d() }); }); });
в native promises-это будет тихий сбой и будет очень трудно отлаживать - с Bluebird promises это покажет большую красную ошибку в вашей консоли по умолчанию, давая вам:
ReferenceError: a is not defined at evenMoreInner (<anonymous>:6:13) From previous event: at inner (<anonymous>:5:24) From previous event: at outer (<anonymous>:4:20) From previous event: at <anonymous>:3:9 at Object.InjectedScript._evaluateOn (<anonymous>:581:39) at Object.InjectedScript._evaluateAndWrap (<anonymous>:540:52) at Object.InjectedScript.evaluate (<anonymous>:459:21)
как только вы закончите отладку - вы можете поменять его и вернуться к родным обещаниям. Лично я ценю, зная, что у меня есть ошибки в производстве, поэтому я не рекомендую его, но это, безусловно, выполнимо.
*это не дает прямого ответа на ваш вопрос, но тем не менее может быть полезно.
Chrome devtools недавно получил новую функцию, которая полезна для отладки асинхронного кода, например Promises.
http://www.html5rocks.com/en/tutorials/developertools/async-call-stack/
в принципе, включите флажок" асинхронный "на вкладке "Источники", и Chrome восстановит стек вызовов для вас, как если бы он был синхронным код.
этот ответ является дополнением к ответу Бенджамина Грюнбаума: Если вы используете оператор catch в цепочке обещаний, вы получите трассировку стека по ошибка.стек:
Promise.longStackTraces(); function outer() { return Promise.resolve(); } function inner() { return Promise.resolve(); } function evenMoreInner() { a.b.c.d() } Promise.resolve() .then(outer) .then(inner) .then(evenMoreInner()) .catch(function (err) { console.log(err.message); console.log(err.stack); });
Сообщение Об Ошибке:
ReferenceError: a is not defined at evenMoreInner (test/test_promise.js:58:17) <<<< HERE's the error! at Context.<anonymous> (test/test_promise.js:64:23)
Они, кажется, работают с инструментами отладки в Chrome. См. эту тему для получения дополнительной информации.
https://code.google.com/p/v8/issues/detail?id=3093
Я не проверял, если это уже в версии dev или бета-версии, но я надеюсь, что это будет в ближайшее время. Затем он может быть включен в обычную версию в январе 2015 года или около того (просто личное предположение, absolutley не обещает, так как я даже не работаю в Google).
лучший способ отладки обещал слушать
unhandledRejection
событиеprocess
.например, вот как вы можете настроить его и сбросить трассировку стека...
process.on('unhandledRejection', (reason, p) => { console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); // Stack Trace console.log(reason.stack); });
вы можете добавить в консоль.журнал() заявление .затем () функция объекта Promise: Вы также можете добавить в .поймать (), если это необходимо.
genericDbCaller(dbName, collectionName, dbFunctionName, params) { return new Promise((resolve, reject) => { DatabaseContext.instance.getDbConn(dbName) .then((dbConn) => { dbConn.get(collectionName)[dbFunctionName].apply(null, params) .then( (docs) =>{ ----->>> console.log(docs); resolve(docs); }) .catch((e)=>{