Конструктор обещаний с отклонением вызова против ошибки броска
в следующем коде:
var p1 = new Promise(function (resolve, reject) {
throw 'test1';
});
var p2 = new Promise(function (resolve, reject) {
reject('test2');
});
p1.catch(function (err) {
console.log(err); // test1
});
p2.catch(function (err) {
console.log(err); // test2
});
есть ли разница между использованием reject
(in p2
) от Promise
api, и бросая ошибку (в p1
) через throw
?
это точно то же самое?
если это то же самое, зачем нам нужен reject
обратный вызов тогда?
4 ответа:
есть ли разница между использованием
reject
(inp2
) отPromise
api, и бросая ошибку (вp1
) черезthrow
?Да, вы не может использовать
throw
асинхронно, в то время какreject
это обратный вызов. Например, некоторое время ожидания:new Promise(_, reject) { setTimeout(reject, 1000); });
это точно то же самое?
нет, по крайней мере, когда другой код следует за вашим заявлением.
throw
немедленно завершает функция решателя, при вызовеreject
продолжает выполнение после того, как "меченая" обещание аннулировано.кроме того, двигатели могут предоставлять другую информацию об отладке исключений, если вы
throw
объекты ошибку.для вашего конкретного примера, вы правы в том, что
p1
иp2
неотличимы от внешнего мира.
нет, нет, эти два полностью идентичны. Единственная разница и зачем нам это нужно
reject
когда вам нужно отклонить асинхронно - например, если вы преобразуете API на основе обратного вызова, возможно, потребуется сигнализировать об асинхронной ошибке.var p = new Promise(function(resolve, reject){ someCallbackApi(function(err, data){ if(err) reject(err); // CAN'T THROW HERE, non promise context, async. else resolve(data); }); });
Я знаю, что это немного поздно, но я действительно не думаю, что любой из этих ответов полностью отвечает на вопросы, которые у меня были, когда я нашел это, вот более полный пример для игры.
var p1 = new Promise(function (resolve, reject) { throw 'test 1.1'; //This actually happens console.log('test 1.1.1'); //This never happens reject('test 1.2'); //This never happens because throwing an error already rejected the promise console.log('test 1.3'); //This never happens }); var p2 = new Promise(function (resolve, reject) { reject('test 2.1'); //This actually happens console.log('test 2.1.1'); //This happens BEFORE the Promise is rejected because reject() is a callback throw 'test 2.2'; //This error is caught and ignored by the Promise console.log('test 2.3'); //This never happens }); var p3 = new Promise(function (resolve, reject) { setTimeout(function() { reject('test 3.1');}, 1000); //This never happens because throwing an error already rejected the promise throw('test 3.2'); //This actually happens console.log('test 3.3'); //This never happens }); var p4 = new Promise(function (resolve, reject) { throw('test 4.1'); //This actually happens setTimeout(function() { reject('test 4.2');}, 1000); //This never happens because throwing an error already rejected the promise console.log('test 4.3'); //This never happens }); var p5 = new Promise(function (resolve, reject) { setTimeout(function() { throw('test 5.1');}, 1000); //This throws an Uncaught Error Exception reject('test 5.2'); //This actually happens console.log('test 5.3'); //This happens BEFORE the Promise is rejected because reject() is a callback }); var p6 = new Promise(function (resolve, reject) { reject('test 6.1'); //This actually happens setTimeout(function() { throw('test 6.2');}, 1000); //This throws an Uncaught Error Exception console.log('test 6.3'); //This happens BEFORE the Promise is rejected because reject() is a callback }); p1.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test1 }); p2.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test2 }); p3.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test3 }); p4.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test4 }); p5.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test5 }); p6.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test6 });
очень интересное наблюдение заключается в том, что если вы используете
throw
он будет обрабатываться сначалаreject
обработчик и затемerror
обработчик, если обработчик отклонения не находится на месте.С блоком обработчика отклонения
var allowed = false; var p1 = new Promise( function(resolve, reject) { if (allowed) resolve('Success'); else // reject('Not allowed'); throw new Error('I threw an error') }) p1.then(function(fulfilled) { console.log('Inside resolve handler, resolved value: ' + fulfilled); }, function(rejected) { console.log('Inside reject handler, rejected value: ' + rejected); }).catch(function(error) { console.log('Inside error handler, error value: ' + error); })
без блока обработчика отклонения
var allowed = false; var p1 = new Promise( function(resolve, reject) { if (allowed) resolve('Success'); else // reject('Not allowed'); throw new Error('I threw an error') }) p1.then(function(fulfilled) { console.log('Inside resolve handler, resolved value: ' + fulfilled); }).catch(function(error) { console.log('Inside error handler, error value: ' + error); })
кроме того, блок catch сможет поймать любую ошибку, брошенную внутри
resolve
обработчик.var allowed = true; var p1 = new Promise( function(resolve, reject) { if (allowed) resolve('Success'); else // reject('Not allowed'); throw new Error('I threw an error') }) p1.then(function(fulfilled) { console.log('Inside resolve handler, resolved value: ' + fulfilled); throw new Error('Error created inside resolve handler block'); }).catch(function(error) { console.log('Inside error handler, error value: ' + error); })
похоже, что лучше всего использовать
throw
, Если вы не можете, если вы используете некоторые асинхронные задачи, вам придется передатьreject
обратный вызов до асинхронной функции. Но есть работа вокруг, то есть для обещания вашей асинхронной функции. Подробнее о https://stackoverflow.com/a/33446005