簡體   English   中英

JavaScript許諾.then和setTimeout排序

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM