Конструктор обещаний с отклонением вызова против ошибки броска
в следующем коде:
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) отPromiseapi, и бросая ошибку (в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