sam*_*sam 211 javascript promise es6-promise
假设我有以下代码.
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if(denominator === 0){
reject("Cannot divide by 0");
return; //superfluous?
}
resolve(numerator / denominator);
});
}
Run Code Online (Sandbox Code Playgroud)
如果我的目的是reject尽早退出,那么我是否应该return立即养成习惯?
Ori*_*ori 298
的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);
});
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它会阻止resolve(numerator / denominator);执行,这不是严格需要的.但是,最好终止执行以防止将来出现可能的陷阱.此外,不必要地防止运行代码是一种很好的做法.
背景
承诺可以是以下三种状态之一:
当承诺得到履行或拒绝时,它将无限期地(定居)保持在这种状态.因此,拒绝履行承诺或履行被拒绝的承诺将不起作用.
此示例代码段显示,虽然承诺在被拒绝后已履行,但仍未被拒绝.
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));Run Code Online (Sandbox Code Playgroud)
那么为什么我们需要回归呢?
虽然我们无法更改已结算的承诺状态,但拒绝或解决将不会停止执行其余功能.该函数可能包含会产生令人困惑的结果的代码.例如:
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));Run Code Online (Sandbox Code Playgroud)
即使该函数现在不包含此类代码,也会产生未来可能的陷阱.未来的重构可能会忽略在拒绝承诺后代码仍然执行的事实,并且很难调试.
解决/拒绝后停止执行:
这是标准的JS控制流程.
resolve/ 之后返回reject: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));Run Code Online (Sandbox Code Playgroud)
resolve/ reject- 因为忽略了回调的返回值,我们可以通过返回reject/resolve语句来保存一行: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));Run Code Online (Sandbox Code Playgroud)
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));Run Code Online (Sandbox Code Playgroud)
我更喜欢使用其中一个return选项,因为代码更平坦.
小智 32
一个常见的习语,可能是也可能不是你的一杯茶,是将the return与the reject,,,同时拒绝承诺并退出函数,以便包括the的函数的其余部分resolve不被执行.如果您喜欢这种风格,它可以使您的代码更紧凑.
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) return reject("Cannot divide by 0");
^^^^^^^^^^^^^^
resolve(numerator / denominator);
});
}
Run Code Online (Sandbox Code Playgroud)
因为无极构造方法不具有任何返回值,并且在任何情况下也能正常工作resolve并reject返回任何结果.
相同的习语可以与另一个答案中显示的回调样式一起使用:
function divide(nom, denom, cb){
if(denom === 0) return cb(Error("Cannot divide by zero"));
^^^^^^^^^
cb(null, nom / denom);
}
Run Code Online (Sandbox Code Playgroud)
同样,这很好用,因为调用的人divide不会期望它返回任何东西而且不会对返回值做任何事情.
use*_*740 10
技术上在这里不需要它1 -因为承诺可以解决或者拒绝,仅仅只有一次.第一个Promise结果获胜,每个后续结果都被忽略.这是不同的节点样式的回调.
也就是说,确保在实际中确切地调用一个是很好的清洁实践,并且实际上在这种情况下,因为没有进一步的异步/延迟处理."早退"的决定与其工作完成时结束任何功能没有什么不同 - 与持续不相关或不必要的处理相比.
在适当的时间返回(或以其他方式使用条件以避免执行"其他"情况)减少了在无效状态下意外运行代码或执行不必要的副作用的机会; 因此,它使代码不易出现"意外破坏".
1这个技术上的答案也取决于这样一个事实,即在这种情况下,"返回"之后的代码,如果省略,将不会产生副作用.JavaScript将很乐意除以零并返回+ Infinity/-Infinity或NaN.
如果您在解决/拒绝后没有"返回",那么在您意图停止之后,可能会发生错误的事情(例如页面重定向).来源:我碰到了这个.
Ori的答案已经解释说没有必要,return但这是好的做法.请注意,promise构造函数是throw安全的,因此它将忽略稍后在路径中传递的抛出异常,基本上你有副作用,你不能轻易观察到.
请注意,return早期回调在回调中也很常见:
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.
}
Run Code Online (Sandbox Code Playgroud)
因此,虽然它是承诺的良好实践,但它需要回调.关于代码的一些注意事项:
在许多情况下,可以单独验证参数并立即使用Promise.reject(reason)返回被拒绝的承诺。
function divide2(numerator, denominator) {
if (denominator === 0) {
return Promise.reject("Cannot divide by 0");
}
return new Promise((resolve, reject) => {
resolve(numerator / denominator);
});
}
divide2(4, 0).then((result) => console.log(result), (error) => console.log(error));Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
61739 次 |
| 最近记录: |