[英]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.