我发现自己编写了很多Promise代码来处理数据可能不可用的情况,并且我不确定在这种情况下是否传递null或throw / catch。
例如:
users.getById(id).then((user) => {
if (!user) {
return null;
}
return doSomething(user);
});
可以写成
users.getById(id).then((user) => {
return doSomething(user);
}).catch((e) => {
// User wasn't found
});
这些中的任何一种在某种程度上通常是优选的还是惯用的,还是最好在每种情况下都遵循我的直觉?
答案 0 :(得分:2)
如果函数被调用users.getById
,那么它的回调应该有一个用户对象,句点。获取用户对象的承诺仅在您实际获得用户对象时才会实现。
抛出typed Error instances表示各种错误情况。
users.getById(id).then((user) => {
return doSomething(user);
}).catch((e) => {
switch (e.Name) {
case "UserNotFound":
// User wasn't found
break;
default:
// unexpected error
}
});
bluebird
承诺库有explicit support for typed exceptions并且单独support for catching operational errors,您可以模仿该行为。或者你可以使用蓝鸟:
users.getById(id).then((user) => {
return doSomething(user);
}).error(UserNotFound, (e) => {
// User wasn't found
}).catch((e) => {
// unexpected error
});
答案 1 :(得分:1)
如果这是一个API调用,通常,您希望为使用者保存throw部分,而不是在内部处理它。
...或在内部处理convert-to-JSON部分,但如果存在加载错误或转换错误,请让外部世界使用oops。
这就是我的意思;我们将跳过承诺一秒钟:
function getData () {
var data = null;
try {
data = getSomeData();
} catch (e) { } // ignore it
return data;
}
var data = getData();
var name = data.property.name; // BOOM
如果它会抛出,你应该抓住它(如果它没有抛出会更好,但更好的是要知道它会抛出,而不是知道)。
function getData () {
var data = getSomeData();
return data;
}
var data;
var name;
try {
data = getData();
name = data.property.name;
} catch (e) { /* now at the right level */ }
当然,投掷总体上并不是很好。根据你对函数式编程的立场,也不是空的。
如果我们做了一个返回承诺的电话:
function getData () {
return callServer()
.then( response => JSON.parse(response) );
}
getData()
.then(showData)
.catch(showError);
如果在内部处理了该错误,它将永远不会让最终用户处理他们的东西丢失的事实。如果您返回null,那么他们必须在null
内进行各种then( )
- 检查。