提早解决/拒绝之后是否需要返回?
假设我有以下代码。
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
目的是在拒绝之后终止函数的执行,并阻止代码执行后的执行。
function divide(numerator, denominator) { return new Promise((resolve, reject) => { if (denominator === 0) { reject("Cannot divide by 0"); return; // The function execution ends here } resolve(numerator / denominator); }); }
在这种情况下,它阻止了resolve(numerator / denominator);
从执行,这是不是严格需要。 但是,最好是终止执行以防止未来陷入可能的陷阱。 另外,防止不必要地运行代码是一个好习惯。
背景
一个承诺可以在3个州之一:
- 待定 – 初始状态。 从待定我们可以移动到其他国家之一
- 履行 – 成功运作
- 拒绝 – 失败的操作
当承诺被履行或被拒绝时,它将无限期地保持这个状态(结算)。 所以,拒绝履行承诺或履行被拒绝的承诺,将不会有效果。
这个例子片断显示,虽然承诺被拒绝后实现,但仍然被拒绝。
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));
一个常见的习惯用法,可能是也可能不是你的一杯茶,就是把这个return
和reject
结合起来,同时拒绝这个承诺,退出这个function,这样包括resolve
在内的其余function就不会被执行。 如果你喜欢这种风格,它可以使你的代码更加紧凑。
function divide(numerator, denominator) { return new Promise((resolve, reject) => { if (denominator === 0) return reject("Cannot divide by 0"); ^^^^^^^^^^^^^^ resolve(numerator / denominator); }); }
这工作正常,因为Promise构造函数没有任何返回值,并在任何情况下resolve
和reject
任何返回。
在另一个答案中显示的callback风格可以使用相同的习惯用法:
function divide(nom, denom, cb){ if(denom === 0) return cb(Error("Cannot divide by zero")); ^^^^^^^^^ cb(null, nom / denom); }
再一次,这工作正常,因为调用divide
的人不希望它返回任何东西,并没有做任何事情的返回值。
从技术上讲 ,这里不需要1 – 因为一个承诺可以被解决或拒绝,只有一次。 第一个Promise结果获胜,并且每个后续结果都被忽略。 这与Node式的callback不同。
这就是说,在实际中确保只有一个被调用是很好的清洁实践 ,事实上在这种情况下,因为没有进一步的asynchronous/延迟处理。 “早退”的决定与完成任务时结束任何function没有什么不同 – 与持续不相关或不必要的处理相比。
在合适的时间返回(或以其他方式使用条件来避免执行“其他”情况)可以减less意外地将代码运行在无效状态或执行不需要的副作用的可能性; 正因如此,它使得代码不太容易“意外突破”。
1这个技术上的答案也取决于这样一个事实,即在这种情况下 ,“返回”之后的代码应该省略,不会导致副作用。 JavaScript会高兴地除以零,并返回+ Infinity / -Infinity或NaN。
Ori的回答已经解释说,没有必要return
但是这是好的做法。 请注意,promise构造函数是安全的,所以它会忽略在path后面传递的exception抛出,本质上你有副作用,你不容易观察。
请注意,早期return
在callback中也很常见:
function divide(nom, denom, cb){ if(denom === 0){ cb(Error("Cannot divide by zero"); return; // unlike with promises, missing the return here is a mistake } cb(null, nom / denom); // this will divide by zero. Since it's a callback. }
所以,虽然承诺是一个很好的实践,但callback需要它。 关于你的代码的一些说明:
- 你的用例是假设的,实际上不用同步操作的promise。
- promise构造函数忽略返回值。 有些图书馆会警告你是否返回一个非未定义的值,以警告你不要再返回那里。 大多数人不聪明。
- 承诺构造函数是安全的,它会将exception转换为拒绝,但正如其他人指出的 – 一个承诺解决一次。
如果在解决/拒绝之后没有“返回”,那么在您停止之后就会发生不好的事情(如页面redirect)。 来源:我碰到了这个。