问:
假设我有如下的代码
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if(denominator === 0){
reject("Cannot divide by 0");
return; //superfluous?
}
resolve(numerator / denominator);
});
}
如果我的目的是利用reject
提前退出,我是否应该在它之后也立刻加一个return
呢?
答:
return
的作用就在于rejection后终止函数的执行,并且阻止后面代码的执行。
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
return; //函数执行到此结束
}
resolve(numerator / denominator);
});
}
在这个例子中它阻止了resolve(numerator / denominator);
的执行,严格意义上这里是不需要return的。但是,仍然建议加上它来立刻阻止执行来避免一些潜在的麻烦。另外,避免执行不必要的代码是一个良好的实践。
背景
一个promise可以处于3种状态中的一种:
- pending - 初始状态。从pending状态我们可以切换到另外的状态
- fulfilled - 成功的操作
- rejected - 失败的操作
当一个promise是fulfilled或者rejected状态时,它将会一直维持该状态。所以,reject一个fulfilled的promise或者fulfill一个rejected的promise是没有任何效果的。
下面的代码片段展示了即使一个promise在rejected后被fulfill,那也是没什么卵用的。
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
}
resolve(numerator / denominator);
});
}
divide(5,0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
// 输出结果
error: Cannot divide by 0
所以我们为什么需要return?
尽管我们无法改变一个已经改变过状态的promise,但是reject和resolve都无法让函数剩下的部分暂停执行。那函数中包含的其他代码可能会对我们造成干扰。举例:
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
}
console.log('operation succeeded');
resolve(numerator / denominator);
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
// 输出结果
operation succeeded
error: Cannot divide by 0
即使函数现在不包含这种代码,也保不齐将来会有。将来的重构者可能会弄不明白,也很难debug。
在resolve/reject后停止执行
这是标准JS控制流程:
- 在
resolve
/reject
后return:
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
return;
}
console.log('operation succeeded');
resolve(numerator / denominator);
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
- return时带上
resolve
/reject
- 因为回调函数的return值是被忽略的,所以我们这里能少写一行代码:
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
return reject("Cannot divide by 0");
}
console.log('operation succeeded');
resolve(numerator / denominator);
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
- 使用 if/else 代码块:
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
} else {
console.log('operation succeeded');
resolve(numerator / denominator);
}
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
我个人是倾向于使用return
的方式的,这样代码看起来比较漂亮。
网友评论