异步承诺失败时首选throw或reject
Prefer throw or reject when failing promise asynchronously
我有一个Bluebird承诺,它包装了一个AJAX请求,并且需要在请求失败时拒绝该承诺。我想提供请求失败的原因,主要从状态码中提取,到可能附加的任何捕获块。为了实现这一点,我有UnauthorizedError
和NotFoundError
以及类似的类,它们都扩展了Error
以与蓝鸟的模式匹配的catch
一起工作。
我不确定的部分是我是否应该throw
或调用拒绝处理程序。我的代码看起来像这样:
class Request {
// other methods
send(method, url, args, body) {
return new Promise((res, rej) => {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = () => {
res(JSON.parse(xhr.responseText));
};
xhr.onerror = () => {
let status = xhr.status;
switch (status) {
case 401:
// Should I use throw:
throw new UnauthorizedError(url);
// or
rej(new UnauthorizedError(url));
}
};
xhr.send();
});
}
}
Promise
构造函数内部
promise构造函数是抛出安全的,但从本质上讲,你通常不会在内部处理抛出安全的事情——因此,例如下面的代码是不安全的:
new Promise(function(resolve, reject){
setTimeout(function(){
// NEVER throw here, it'll throw globally and not reject the promise
}, 100);
});
promise构造函数通常只用于将回调api转换为承诺,由于回调不像承诺那样具有抛出安全,因此当它们异步出错(而不是抛出)时,您必须拒绝。
then
处理程序内部
两者功能相同。当您从then
处理程序中执行throw
时,您将返回一个被拒绝的承诺。我更喜欢throw,因为它比return
更明确地表明发生了错误,但这并不重要。
对于除Angular 1之外的任何承诺实现都是如此。x的$q
区分两者-但它是奇怪的球(当你throw
在那里它记录,即使你处理错误)。
在你的代码
在你的代码中,拒绝和处理承诺的方式有几个bug。承诺是非常健壮的,因为它们为你优雅地处理错误——在这方面,当你将回调api转换为承诺时,你必须非常小心:
class Request {
// other methods
send(method, url, args, body) {
return new Promise((res, rej) => { // it's good that new Promise is the first
let xhr = new XMLHttpRequest(); // line since it's throw-safe. This is why it
xhr.open(method, url); // was chosen for the API and not deferreds
xhr.onload = () => {
// This _needs_ a try/catch, it will fail if responseText
// is invalid JSON and will throw to the global scope instead of rejecting
res(JSON.parse(xhr.responseText));
};
xhr.onerror = () => {
let status = xhr.status;
switch (status) {
case 401:
// this _must_ be a reject, it should also generally be surrounded
// with a try/catch
rej(new UnauthorizedError(url));
}
};
xhr.send(); // it's important that this is in the promise constructor
});
}
}
相关文章:
- 函数参数在内部不可见,返回新的Promise(函数(resolve,reject).传递给被promise化的函数的
- $q.reject和处理AngularJS链接承诺中的错误
- Angular $q.reject().success(),这有意义吗?
- $provide.decorator$controller return throw undefined不是angula
- 当“new constructor()”与mocha和chai一起使用时,我如何断言throw
- 为什么我们必须在es6箭头函数中用括号包装throw
- 带IndexOf的Undercore reject函数从数组中删除所有对象
- Jquery iterate throw json
- 节点服务器响应错误: process.nextTick(function(){throw err;});.
- .NET 4上的ASP.NET导致IE11 throw _doPostBack是未定义的javascript错误
- Use coffeescript/javascript 'throw error' or 'th
- 为什么在 Promise.all() 之后没有调用 onJect,其中数组中包含的 Promise.reject() 传
- 在Javascript表达式中使用throw
- 在JavaScript中,“throw”之后需要“return”吗
- What is the point of "throw"?
- throw Error和console.error的区别是什么?
- 何时或谁将resolve和reject函数传递给JS承诺
- Model.reject()会在extjs格式中产生无效字段
- $q.reject上未调用$routeChangeError
- 异步承诺失败时首选throw或reject