javascript 带有拒绝调用的承诺构造函数与抛出错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28703241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Promise constructor with reject call vs throwing error
提问by lante
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
?
从api使用reject
(in p2
)Promise
和使用 抛出错误 (in p1
)之间有什么区别throw
吗?
Its exactly the same?
它完全一样吗?
If its the same, why we need a reject
callback then?
如果相同,那为什么我们需要reject
回调呢?
回答by Bergi
Is there any difference between using
reject
(inp2
) from thePromise
api, and throwing an error (inp1
) usingthrow
?
从api使用
reject
(inp2
)Promise
和使用 抛出错误 (inp1
)之间有什么区别throw
吗?
Yes, you cannotuse throw
asynchronously, while reject
is a callback. For example, some timeout:
是的,您不能throw
异步使用,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.
不,至少当其他代码遵循您的语句时不会。throw
立即完成解析器功能,同时调用reject
继续正常执行 - 在将承诺“标记”为拒绝后。
Also, engines might provide different exception debugging information if you throw
error objects.
此外,如果您throw
错误对象,引擎可能会提供不同的异常调试信息。
For your specific example, you are right that p1
and p2
are indistinguishable from the outside.
对于您的具体示例,您是对的,p1
并且p2
与外部无法区分。
回答by Benjamin Gruenbaum
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.
不,没有,两者完全相同。唯一的区别以及我们需要的原因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);
});
});
回答by Jonathan Rys
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
});
回答by Gavin
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
它,它将首先由reject
处理程序处理,然后在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 块将能够捕获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);
})
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://stackoverflow.com/a/33446005
看起来最好使用throw
,除非您不能运行某些异步任务,否则您必须将reject
回调传递给异步函数。但是有一个变通方法,那就是承诺你的异步功能。更多关于https://stackoverflow.com/a/33446005