练习题
题一:Retry
Say you have a function primitiveMultiply that in 20 percent of cases multiplies two numbers and in the other 80 percent of cases raises an exception of type MultiplicatorUnitFailure. Write a function that wraps this clunky function and just keeps trying until a call succeeds, after which it returns the result.
Make sure you handle only the exceptions you are trying to handle.
我最开始写了一个复杂的版本,用到了try catch finally:
class MultiplicatorUnitFailure extends Error{}
function primitiveMultiply(x, y) {
let randomNumber = Math.trunc(Math.random() * 101);
console.log(randomNumber); // 查看生成的randomNumber到底是多少
if (randomNumber <= 20) return x * y;
else {
throw new MultiplicatorUnitFailure();
}
}
function multiplication(x, y) {
let multiplicationResult = undefined;
let retry = 1;
while (retry) {
try {
multiplicationResult = primitiveMultiply(x, y);
} catch (error) {
if (error instanceof MultiplicatorUnitFailure) {
console.log("Continue to call the primitiveMultiply()");
}
} finally {
if (multiplicationResult !== undefined) {
console.log("We have got the multiplication result. ");
retry = null;
}
}
}
return multiplicationResult;
}
第二次,我对multiplication(x, y)进行了改进,只用到try catch:
function multiplication(x, y) {
let multiplicationResult = undefined;
let retry = 1;
while (retry) {
try {
multiplicationResult = primitiveMultiply(x, y);
retry = null;
} catch (error) {
if (error instanceof MultiplicatorUnitFailure) {
console.log("Continue to call the primitiveMultiply()");
}
}
}
return multiplicationResult;
}
因为当程序运行到retry = null的时候,说明上一行的代码已经顺利完成,就可以跳出while循环了。
作者给出的答案如下:
class MultiplicatorUnitFailure extends Error {}
function primitiveMultiply(a, b) {
if (Math.random() < 0.2) {
return a * b;
} else {
throw new MultiplicatorUnitFailure('Klunk');
}
}
function reliableMultiply(a, b) {
for (;;) {
try {
return primitiveMultiply(a, b);
} catch (e) {
if (!(e instanceof MultiplicatorUnitFailure)) throw e;
}
}
}
也就是说,作者用到的是for(;;),学到了,哈哈哈。return primitiveMultiply(a, b)这一行代码顺利执行完(没有throw exception),自然就跳出了for loop。