在JavaScript函数中,哪个return ?
function test() {
return 'one';
return 'two';
return 'three';
}
你可能会说,"嗯,是第一个",但我要尝试说服你是最后一个。
别担心,上面的函数肯定会返回'one' ,但在这种情况下,第一个返回语句会阻止其他语句的执行。最后一个返回值是return 'one' ,这才是赢家。当然,这也是第一个返回,但我仍然是对的。[折叠手臂,看起来很得意]
我知道你在想什么,你在想 "闭嘴,Jake",但请忍耐一下......
最后
finally 是一个东西:
function finallyTest() {
try {
console.log('one');
return 'three';
} catch (err) {
console.log('error');
} finally {
console.log('two');
}
}
console.log(finallyTest());
console.log('four');
上面的日志'one','two','three','four' 。finally 块总是在try/catch 之后运行,即使try 或catch 返回。
直到最近,我发现自己在异步函数中像这样使用finally ,我才在JavaScript中使用了很多:
async function someAsyncThing() {
startSpinner();
try {
await asyncWork();
} catch (err) {
if (err.name === 'AbortError') return;
showErrorUI();
} finally {
stopSpinner();
}
}
总之,关于finally ,令人兴奋的是它让我们有机会从一个函数调用中多次返回:
function manyHappyReturns() {
try {
return 'one';
} finally {
try {
return 'two';
} finally {
return 'three';
}
}
}
...而调用manyHappyReturns() 的结果是'three' 。
最后的返回总是赢的。不是在函数中最后出现的,不,那会很疯狂,而是最后执行的。最后一个返回获胜的方式与最后一个变量赋值获胜的方式相同;我们不计算那些没有发生的变量赋值。事实上,它的规格很像一个赋值。return 为函数分配了一个结论,所以一个return 覆盖了之前的return 。同样的情况也发生在Java和Python中。感谢Daniel Ehrenberg让我意识到了这个小怪癖!
作为一个副作用,从finally 返回会清除一个抛出的错误:
function catchThis() {
try {
throw Error('boom');
} finally {
return 'phew';
}
}
调用catchThis() 的结果是'phew' 。
这有什么实际应用吗?
没有。谢谢你的阅读!请不要在求职面试时问别人这个问题。
奖励:承诺
异步函数的行为与上述相同(除了返回一个承诺)。然而,promise.finally() 的行为是不同的:
const promise = Promise.resolve('one').finally(() => 'two');
在这里,promise 与'one' 一起完成。这可能是因为承诺反应是回调,而回调的调用者(在这种情况下就是承诺)没有办法分辨运行return undefined 的函数和根本不运行return 的函数之间的区别。由于它不能模仿上面的finally 的边缘情况,所以它只是忽略了它。
虽然,promise.finally 确实会影响承诺的解决时间:
const wait = (ms) => new Promise((r) => setTimeout(() => r(), ms));
const promise = Promise.resolve('one').finally(async () => {
await wait(2000);
return 'two';
});
在这种情况下,promise 仍然与'one' 一起实现,但需要两秒钟才能完成。