Вместо обратных вызовов, которые не существуют в CSS, мы можем использовать свойство transition-delay
.
#selector {
overflow: hidden; // hide the element content, while height = 0
height: 0; opacity: 0;
transition: height 0ms 400ms, opacity 400ms 0ms;
}
#selector.visible {
height: 100%; opacity: 1;
transition: height 0ms 0ms, opacity 600ms 0ms;
}
Итак, что здесь происходит?
visible
, обе height
и opacity
запускают анимацию без задержки (0 мс), хотя height
принимает 0 мс для завершения анимации (эквивалент display: block
), а opacity
занимает 600 мс. visible
удален, opacity
запускает анимацию (0 мс задержка, 400 мс), а высота ждет 400 мс и только затем мгновенно восстанавливает начальное значение (эквивалент display: none
в обратном вызове анимации) . Обратите внимание, что этот подход лучше, чем при использовании visibility
. В этом случае элемент все еще занимает пространство на странице, и это не всегда удобно.
Для получения дополнительных примеров обратитесь к этой статье .
Да обещает ошибки проглатывания, и вы можете поймать их только с помощью .catch
, как объяснено более подробно в других ответах. Если вы находитесь в Node.js и хотите воспроизвести нормальное поведение throw
, выполните трассировку стека стека на консоль и процесс завершения, вы можете сделать
...
throw new Error('My error message');
})
.catch(function (err) {
console.error(err.stack);
process.exit(0);
});
Согласно spec (см. 3.III.d) :
d. Если вызов затем выдает исключение e, & nbsp; & nbsp; a. Если вы вызываете resolvePromise или rejectPromise, игнорируйте его. & NBSP; & NBSP; б. В противном случае, отклоните обещание с e в качестве причины.
blockquote>Это означает, что если вы выбрали исключение в функции
then
, оно будет поймано, и ваше обещание будет отклонено.catch
не имеет смысла здесь, это просто ярлык для.then(null, function() {})
Я предполагаю, что вы хотите регистрировать необработанные отклонения в коде. Большинство библиотек обещаний запускает для него
unhandledRejection
. Вот соответствующий gist с обсуждением об этом.
Я знаю, что это немного поздно, но я столкнулся с этой нитью, и ни одно из решений не было легко реализовать для меня, поэтому я придумал свой собственный:
Я добавил немного помощника функция, которая возвращает обещание, например:
function throw_promise_error (error) {
return new Promise(function (resolve, reject){
reject(error)
})
}
Тогда, если у меня есть определенное место в любой из моих цепочек обещаний, где я хочу выбросить ошибку (и отвергнуть обещание), я просто возвращаю из приведенной выше функции с моей сконструированной ошибкой, например:
}).then(function (input) {
if (input === null) {
let err = {code: 400, reason: 'input provided is null'}
return throw_promise_error(err)
} else {
return noterrorpromise...
}
}).then(...).catch(function (error) {
res.status(error.code).send(error.reason);
})
Таким образом, я контролирую выброс лишних ошибок из цепочки обещаний. Если вы хотите также обрабатывать «нормальные» обещания, вы можете расширить свой улов, чтобы обрабатывать «самозаброшенные» ошибки отдельно.
Надеюсь, что это поможет, это мой первый ответ на stackoverflow!
Я попробовал метод setTimeout()
, подробно описанный выше ...
.catch(function(err) { setTimeout(function() { throw err; }); });
Раздражающе, я обнаружил, что это абсолютно неуместно. Поскольку он выдает асинхронную ошибку, вы не можете обернуть ее внутри оператора try/catch
, потому что catch
перестанет прослушиваться по ошибке времени.
Я вернул только использование прослушивателя который отлично работал и, поскольку он предназначен для использования JavaScript, был высоко проверяемым.
return new Promise((resolve, reject) => {
reject("err");
}).catch(err => {
this.emit("uncaughtException", err);
/* Throw so the promise is still rejected for testing */
throw err;
});
Важные вещи, чтобы понять здесь
then
и catch
возвращают новые объекты обещания. then
и catch
возвращают новые объекты обещания, они могут быть привязаны. then
или catch
), он будет обрабатываться в следующем обработчике отклонения по пути цепочки. then
и catch
не выполняются синхронно. Когда обработчик бросает, он немедленно прекратится. Таким образом, стек будет размотан, и исключение будет потеряно. Вот почему бросание исключения отвергает текущее обещание. В вашем случае вы отклоняете внутри do1
, бросая объект Error
. Теперь текущее обещание будет в состоянии отклонения, и управление будет передано следующему обработчику, который в нашем случае then
.
Поскольку обработчик then
не имеет обработчика отклонения , do2
не будет выполняться вообще. Вы можете подтвердить это, используя console.log
внутри него. Поскольку текущее обещание не имеет обработчика отклонения, оно также будет отклонено с использованием значения отклонения от предыдущего обещания, и управление будет передано следующему обработчику, который является catch
.
Поскольку catch
является обработчиком отклонения, когда вы console.log(err.stack);
внутри него, вы можете видеть трассировку стека ошибок. Теперь вы выбрасываете из него объект Error
, так что обещание, возвращенное catch
, также будет находиться в состоянии отклонения.
Поскольку вы не привязали обработчик отклонения к catch
, вы неспособный наблюдать отклонение.
Вы можете разделить цепочку и понять это лучше, например
var promise = do1().then(do2);
var promise1 = promise.catch(function (err) {
console.log("Promise", promise);
throw err;
});
promise1.catch(function (err) {
console.log("Promise1", promise1);
});
. Вы получите то, что вы получите
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
Внутри обработчика catch
вы получаете значение promise
объекта как отклоненного.
То же самое, обещание, возвращаемое обработчиком catch
1, также отклоняется с той же ошибкой, с которой promise
был отклонен, и мы наблюдаем его во втором обработчике catch
.
Как объяснили другие, «черная дыра» заключается в том, что метание внутри .catch
продолжает цепочку с отклоненным обещанием, и у вас больше нет уловов, что приводит к неразрывной цепочке, которая проглатывает ошибки (плохие!)
Добавьте еще один улов, чтобы увидеть, что происходит:
do1().then(do2).catch(function(err) {
//console.log(err.stack); // This is the only way to see the stack
throw err; // Where does this go?
}).catch(function(err) {
console.log(err.stack); // It goes here!
});
Улов в середине цепочки полезен, когда вы хотите, чтобы цепочка продолжалась, несмотря на неудачный шаг, но повторный бросок полезен для continue failing после выполнения таких действий, как ведение журнала информации или шагов очистки, возможно, даже изменение этой ошибки.
Чтобы ошибка возникла как ошибка в веб-консоли, как вы изначально планировали, я использую этот трюк:
.catch(function(err) { setTimeout(function() { throw err; }); });
Even номера строк выживают, поэтому ссылка в веб-консоли выводит меня прямо в файл и строку, где произошла ошибка (оригинальная).
Любое исключение в функции, называемой поскольку обработчик выполнения обещаний или отклонения автоматически преобразуется в отказ от обещания, которое вы должны вернуть. Код обещания, который вызывает вашу функцию, позаботится об этом.
Функция, вызываемая setTimeout, с другой стороны, всегда работает из стабильного состояния JavaScript, то есть работает в новом цикле в цикле событий JavaScript. Исключения там не пойманы ничем и не попадают в веб-консоль. Поскольку err
содержит всю информацию об ошибке, включая исходный стек, номер файла и строки, он по-прежнему сообщается правильно.