In the following code:
在以下代码:
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
});
Is there any difference between using reject
(in p2
) from the Promise
api, and throwing an error (in p1
) using throw
?
在Promise api中使用reject(在p2中)和使用throw抛出错误(在p1中)之间有什么区别吗?
Its exactly the same?
一模一样的吗?
If its the same, why we need a reject
callback then?
如果它是相同的,那么为什么我们需要一个拒绝回调呢?
4 个解决方案
#1
56
Is there any difference between using
reject
(inp2
) from thePromise
api, and throwing an error (inp1
) usingthrow
?在Promise api中使用reject(在p2中)和使用throw抛出错误(在p1中)之间有什么区别吗?
Yes, you cannot use throw
asynchronously, while reject
is a callback. For example, some timeout:
是的,不能异步地使用抛出,而reject是回调。例如,一些超时:
new Promise(_, reject) {
setTimeout(reject, 1000);
});
Its exactly the same?
一模一样的吗?
No, at least not when other code follows your statement. throw
immediately completes the resolver function, while calling reject
continues execution normally - after having "marked" the promise as rejected.
不,至少当其他代码遵循您的语句时不会。抛出立即完成解析器函数,而调用拒绝在正常情况下继续执行——在“标记”了被拒绝的承诺之后。
Also, engines might provide different exception debugging information if you throw
error objects.
此外,如果抛出错误对象,引擎可能会提供不同的异常调试信息。
For your specific example, you are right that p1
and p2
are indistinguishable from the outside.
对于您的具体示例,您是对的,p1和p2与外部是不可区分的。
#2
30
No, there is not, the two are completely identical. The only difference and why we need reject
is when you need to reject asynchronously - for example if you're converting a callback based API it might need to signal an asynchronous error.
不,没有,这两个完全相同。唯一的区别和我们需要拒绝的原因是当您需要异步拒绝时—例如,如果您正在转换一个基于回调的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);
});
});
#3
28
I know this is a bit late, but I don't really think either of these answers completely answers the questions I had when I found this, Here is a fuller example to play with.
我知道这有点晚了,但我不认为这两个答案能完全回答我发现这个问题时的问题,这里有一个更完整的例子。
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
});
#4
0
A very interesting observation is that if you use throw
it will be handled by first the reject
handler & then theerror
handler if a reject handler is not in place.
一个非常有趣的观察是,如果您使用throw,它将首先由拒绝处理程序处理,如果拒绝处理程序不存在,则由error处理程序处理。
With reject handler block
与拒绝处理程序块
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);
})
Without reject handler block
没有拒绝处理程序块
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);
})
Additionally, the catch block will be able catch any error thrown inside the resolve
handler.
此外,catch块将能够捕获在解析处理程序中抛出的任何错误。
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);
})
It looks like it's best to use throw
, unless you can't if you are running some async task, you will have to pass the reject
callback down to the async function. But there's a work around, that is is to promisifying your async function. More on https://*.com/a/33446005
看起来最好使用throw,除非您在运行异步任务时不能使用,否则必须将拒绝回调传递给async函数。但是有一个工作,那就是推广你的异步函数。在https://*.com/a/33446005上更
#1
56
Is there any difference between using
reject
(inp2
) from thePromise
api, and throwing an error (inp1
) usingthrow
?在Promise api中使用reject(在p2中)和使用throw抛出错误(在p1中)之间有什么区别吗?
Yes, you cannot use throw
asynchronously, while reject
is a callback. For example, some timeout:
是的,不能异步地使用抛出,而reject是回调。例如,一些超时:
new Promise(_, reject) {
setTimeout(reject, 1000);
});
Its exactly the same?
一模一样的吗?
No, at least not when other code follows your statement. throw
immediately completes the resolver function, while calling reject
continues execution normally - after having "marked" the promise as rejected.
不,至少当其他代码遵循您的语句时不会。抛出立即完成解析器函数,而调用拒绝在正常情况下继续执行——在“标记”了被拒绝的承诺之后。
Also, engines might provide different exception debugging information if you throw
error objects.
此外,如果抛出错误对象,引擎可能会提供不同的异常调试信息。
For your specific example, you are right that p1
and p2
are indistinguishable from the outside.
对于您的具体示例,您是对的,p1和p2与外部是不可区分的。
#2
30
No, there is not, the two are completely identical. The only difference and why we need reject
is when you need to reject asynchronously - for example if you're converting a callback based API it might need to signal an asynchronous error.
不,没有,这两个完全相同。唯一的区别和我们需要拒绝的原因是当您需要异步拒绝时—例如,如果您正在转换一个基于回调的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);
});
});
#3
28
I know this is a bit late, but I don't really think either of these answers completely answers the questions I had when I found this, Here is a fuller example to play with.
我知道这有点晚了,但我不认为这两个答案能完全回答我发现这个问题时的问题,这里有一个更完整的例子。
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
});
#4
0
A very interesting observation is that if you use throw
it will be handled by first the reject
handler & then theerror
handler if a reject handler is not in place.
一个非常有趣的观察是,如果您使用throw,它将首先由拒绝处理程序处理,如果拒绝处理程序不存在,则由error处理程序处理。
With reject handler block
与拒绝处理程序块
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);
})
Without reject handler block
没有拒绝处理程序块
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);
})
Additionally, the catch block will be able catch any error thrown inside the resolve
handler.
此外,catch块将能够捕获在解析处理程序中抛出的任何错误。
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);
})
It looks like it's best to use throw
, unless you can't if you are running some async task, you will have to pass the reject
callback down to the async function. But there's a work around, that is is to promisifying your async function. More on https://*.com/a/33446005
看起来最好使用throw,除非您在运行异步任务时不能使用,否则必须将拒绝回调传递给async函数。但是有一个工作,那就是推广你的异步函数。在https://*.com/a/33446005上更