MDN 上的说明 "Use functions instead of evaluating snippets of code" - 为什么?
Clarifications on MDN "Use functions instead of evaluating snippets of code" - why's that?
在关于 eval
的 MDN 文章中有一个标题为 Use functions instead of evaluating snippets of code 的段落,在示例代码中有一个关于 setTimeout() 的参考。我不明白为什么这个 advice/command,所以,保留 setTimeout() 参考,有人能指出我为什么这些代码按预期工作吗:
function timedPromise(){
return new Promise((resolve) => {
setTimeout(( ) => {resolve(console.log('Promise resolved!'))}, 1000)
})
};
function timedPromise2(){
return new Promise((resolve) => {
setTimeout(function(){resolve(console.log('Another promise resolved!'))}, 2000)
})
};
timedPromise();
timedPromise2();
/*output:
Promise {<pending>}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
Promise resolved! //after at least 1s
Another promise resolved! //after at least 2s
*/
虽然这段代码不会?
function timedPromise(){
return new Promise((resolve) => {
setTimeout(resolve(console.log('I resolved!')), 1000)
})
};
timedPromise();
/*output:
I resolved! //immediate
Promise {<fulfilled>: undefined}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
*/
我理解浏览器将代码片段评估为string
而不是函数,然后立即解释并执行它,而不是等待 setTimeout() 的延迟过去。
为什么?
Why/when 我应该使用包装函数而不是代码片段作为参数吗?是不是只和异步有关的东西?
当你写functionName()
时,()
会立即调用该函数。
所以当你写 setTimeout(resolve(console.log('I resolved!')), 1000)
时:
- 首先调用
console.log
将其 return 值传递给 resolve
;
- 调用
resolve
将其值传递给 setTimeout
;
- 通话
setTimeout
。
当您将函数包装在 lambda 中时,您是在将 reference 传递给该函数,而不是立即调用它。这样看可能更清楚:
function doLog() { console.log("Hello, world!"); }
// Calls doLog instantly, passes in return value of undefined
setTimeout(doLog(), 1000);
// Passes in a reference to doLog, which setTimeout will then call later
setTimeout(doLog, 1000);
在关于 eval
的 MDN 文章中有一个标题为 Use functions instead of evaluating snippets of code 的段落,在示例代码中有一个关于 setTimeout() 的参考。我不明白为什么这个 advice/command,所以,保留 setTimeout() 参考,有人能指出我为什么这些代码按预期工作吗:
function timedPromise(){
return new Promise((resolve) => {
setTimeout(( ) => {resolve(console.log('Promise resolved!'))}, 1000)
})
};
function timedPromise2(){
return new Promise((resolve) => {
setTimeout(function(){resolve(console.log('Another promise resolved!'))}, 2000)
})
};
timedPromise();
timedPromise2();
/*output:
Promise {<pending>}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
Promise resolved! //after at least 1s
Another promise resolved! //after at least 2s
*/
虽然这段代码不会?
function timedPromise(){
return new Promise((resolve) => {
setTimeout(resolve(console.log('I resolved!')), 1000)
})
};
timedPromise();
/*output:
I resolved! //immediate
Promise {<fulfilled>: undefined}
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined
*/
我理解浏览器将代码片段评估为string
而不是函数,然后立即解释并执行它,而不是等待 setTimeout() 的延迟过去。
为什么?
Why/when 我应该使用包装函数而不是代码片段作为参数吗?是不是只和异步有关的东西?
当你写functionName()
时,()
会立即调用该函数。
所以当你写 setTimeout(resolve(console.log('I resolved!')), 1000)
时:
- 首先调用
console.log
将其 return 值传递给resolve
; - 调用
resolve
将其值传递给setTimeout
; - 通话
setTimeout
。
当您将函数包装在 lambda 中时,您是在将 reference 传递给该函数,而不是立即调用它。这样看可能更清楚:
function doLog() { console.log("Hello, world!"); }
// Calls doLog instantly, passes in return value of undefined
setTimeout(doLog(), 1000);
// Passes in a reference to doLog, which setTimeout will then call later
setTimeout(doLog, 1000);