[英]JavaScript promises .then and setTimeout ordering
getAllUsers(): void { this.allUsers = this.userService.getUsers() .then(res => this.allUsers = res) .then(() => setTimeout( () => this.allUsers.forEach( user => console.log(user)), 2000 )) .then(() => setTimeout(this.restOfInit(), 4000)) .catch((error) => console.log(error))); // console.log(this.allUsers[0]); // setTimeout(() => console.log(this.allUsers[0]), 3000); }
在所附的代码段中,我希望所有用户的日志记录都在restOfInit
函数之前进行,因为超时之间相差2秒。 但是,实际上发生的是, restOfInit
运行restOfInit
,将字符串记录到控制台,然后将所有用户记录到控制台。 为什么会这样呢?
两件事情:
1)传递给setTimeout()
)的函数大约在指定的毫秒数内异步执行。 您可能知道这一点。 但是,对setTimeout()
的调用将返回(几乎立即),而不考虑指定的时间。
2)您想传递this.restOfInit
而不是this.restOfInit()
。 前者将函数传递给setTimeout()
。 后者不带任何参数调用该函数,并将返回值(可能是undefined
)传递给setTimeout()。
tldr;
.then(() => setTimeout(this.restOfInit(), 4000)) // Change this line
.then(() => setTimeout(this.restOfInit, 4000)) // to this
就像@fvgs正确指出的那样,您看到的触发顺序的问题在于this.restOfInit
的立即调用-其返回值传递给setTimeout
而不是函数本身。
但是,在此使用超时将无法兑现承诺。 承诺应该允许您精确地安排订单,并且将尽可能快地执行订单,而不是保证的等待期,无论您对用户的请求有多快。 实际上,您的链接根本不需要链接,因为只有第一个回调需要分辨率值。 这样安排时间会容易得多...
getAllUsers(): void {
this.userService.getUsers()
.then(res => {
this.allUsers = res
this.allUsers.forEach(user => console.log(user))
this.restOfInit()
})
.catch((error) => console.log(error)));
}
另外要注意的是-分配this.allUsers = this.userService.getUsers()
链是一个承诺,但随后在回调中分配this.allUsers = res
,从外观this.allUsers = res
,它将是一个数组。 我怀疑这可能是您使用setTimeout
的原因,因为当您不期望它时,它可能会覆盖它。
除非您需要与this.allUsers = this.userService.getUsers()
链进一步交互,否则不需要this.allUsers = this.userService.getUsers()
因此我在上面的代码中省略了此方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.