我有下面的代码,我尝试用console.log
递归setTimeout
计数器。我当时正在开发两个版本,但是每个版本都出现错误。
在第一个中,我不确定为什么setTimeout
没有将this.timeTest
视为函数。
第二,我知道this.timeTest
在范围之外。
有没有办法将其纳入范围?
服务器
const express = require('express')
const app = express()
const port = 3000
const time = require('./timeoutFun.js')
time.timeTest()
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
尝试1
const time = {
counter: 0,
timeTest: function() {
this.counter++
console.log(this.counter)
if (this.counter < 5) {
this.timeTest()
} else if (this.counter === 10) {
console.log("done")
} else {
setTimeout(this.timeTest(), 3000);
}
}
}
module.exports = time;
尝试2
const time = {
counter: 0,
timeTest: function() {
this.counter++
if (this.counter < 5) {
console.log("start")
console.log(this.counter)
this.timeTest()
} else if (this.counter === 10) {
console.log("done")
} else {
setTimeout(function () {
console.log("wait")
console.log(this.counter)
this.timeTest()
}, 3000);
}
}
}
module.exports = time;
答案 0 :(得分:1)
在第一个示例中,您传递的是调用#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
int main() {
pid_t child_pid = fork();
if (child_pid == 0) { // child
int i = 0;
for (;;) {
printf("printing..%d\n", i++);
}
} else {
char userinput[1024];
for (;;) {
fgets(userinput, sizeof(userinput), stdin);
if (strcmp(userinput, "stop\n") == 0) {
kill(child_pid, SIGSTOP);
break;
}
}
}
return 0;
}
函数的结果,而不是函数 的 :
timeTest
对于第二个示例,setTimeout(this.timeTest(), 3000); // wrong
setTimeout(this.timeTest, 3000); // right
确实超出了范围,因为在this.timeTest
调用中引入匿名函数会创建一个新的“上下文”,我的意思是{{1 }}。在javascript中,如果要替换分配给匿名函数的默认上下文,则可以使用上下文绑定函数bind
。
对于新手来说,使用javascript有点复杂,这里不需要这样做-只需修复上面的第一个示例,它将按预期工作。
但是为了后代,这是解决第二个示例的方法:
setTimeout
您还可以使用称为arrow functions的方法,而不是为函数体分配新的上下文,而是为其分配封闭范围的上下文(请注意,仅在ES6中可用)。
this
答案 1 :(得分:1)
更改此:
setTimeout(function () {
console.log("wait")
console.log(this.counter)
this.timeTest()
}.bind(this), 3000); // note the bind invocation here
对此:
setTimeout(() => { // no need for manual binding
console.log("wait")
console.log(this.counter)
this.timeTest()
}, 3000);
setTimeout(this.timeTest(), 3000)
以setTimeout(this.timeTest, 3000)
作为第一个参数。您将传递该函数的结果作为第一个参数,而不是传递函数本身。