<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                新人初步學習JAVASCIPRT時,一般都會在兩個關鍵點上犯迷糊。第一個關鍵點異步,第二個關鍵點是回調。回調 --- callback,與其對應的是調用 ---- call。 # DEMO 上一小節中使用將`function`傳入`subscribe`方法實現了:當訪問請求成功時,將請求的結果賦值給title的作用。`subscribe`方法是如何做到的呢,下面的代碼段展示了其基本原理。 ```javascript var demo = { subscribe: function (success, error) { // 獲取隨機值 var random = Math.floor(Math.random() * 100); // 根據隨機值選擇執行方法 if (random % 2) { // 并不知道success方法的作用也不關心它的作用 // 當滿足偶數時,就調用success方法。 success(random); } else { // 并不知道error方法的作用也不關心它的作用 // 當滿足奇數時,就調用error方法 error(random); } } } function success(randomNumber) { console.log('我是第一個方法,接收到的值為' + randomNumber); } function error(randomNumber) { console.log('我是第二個方法,接收到的值為' + randomNumber); } function success1(randomNumber) { console.log('success1' + randomNumber); } function error1(randomNumber) { console.log('error1' + randomNumber); } // 偶數時執行success, 奇數時執行error。 demo.subscribe(success, error); // 偶數時執行success1, 奇數時執行error1。 demo.subscribe(success1, error1); ``` 總結:JS支持將函數作用參數進行傳遞。被調用的方法在接收到該函數類型的參數時,決定是否調用及何時調用該參數,最終完成回調操作。這種在被調用方法中執行調用方法的模式便稱為回調。而在調用某方法時,傳入某個參數的函數便稱為回調函數。 # 生活中的回調 **調用**情景: 以前我去KFC,在前臺點了一杯3元的可樂,然后在前臺等待著可樂灌裝完成并遞給自己。接著開始喝可樂。喝完可樂后,感覺KFC環境還可以同時還有免費的WIFI。所以我又玩了會手機、刷了會微博。 對應代碼: ``` let cola = kfc.orderCola(3); ? this.drink(cola); ? this.playPhone(); ? this.refreshWeibo(); ? ``` 上述過程即是調用,我是調用的發起方,KFC是調用的執行方。KFC按我的要求進行處理,并將處理的結果返回給我,而在KFC處理我的訂單的過程中,我一直未離開前臺進行等待。 執行順序永遠是:???? > 有些時候,我在等待的時候還不愿意從點餐口那離開,從而無意識的耽誤了后面的顧客點餐桌,便形成了短暫的堵塞。是的,計算機的同步也存在堵塞這個問題。 **回調**情景: 你去KFC,在自動終端上點了一杯3元的可樂,自助終端給你了一張編號為123的憑證。然后你隨便找了個地坐了下來,悠閑的計劃玩玩手機,刷刷微博。KFC在可樂灌裝完成后,服務員喊道:編號123的顧客請到前臺聚餐。我停下刷微博的腳步,拿上可樂并開始享受它。 對應代碼: ``` kfc.orderCola(3, function number123(cola: Cola) { ? this.drink(cola); ? }); this.playPhone(); ? this.refreshWeibo(); ? ``` 上述情景中,在`服務員喊道`的時刻便發生`回調`。沒有回調以前,只能是我們主動向服務員發起調用,但有了`回調`以后,服務員便可以在完成灌裝后主動和我們打招呼了。 上述情景的執行順序為:????。在現實生活中,這個順序不是固定的。比如下次我再去買可樂的時候,餐廳的人沒有那么多了,那么KFC的服務員灌裝的時間就會小很多,所以我游戲沒玩完,人就已經通知我拿可樂了。此時,執行的順序便是????。在計算機也是這樣的,相同的上述代碼執行兩次,這兩次的執行順序也是可能不一樣的。也就是說,我們并不知道KFC的服務員最近的效率如何。最近效率高,就會通知的快一些,最近效率低就會通知的慢一些。實際生活中是這樣,在程序中也是這樣。 > 當我們向KFC服務員發起`購買`之后,KFC服務員可以在接下來在某一個時刻來`通知`我們。這個過程中的`購買`便是`調用`,而`通知`便是`回調`。 # 回調的特點 有了現實生活中活生生的例子,相信總結一下它的規律便不難了: ① 在購買可樂的時候,形成了一個契約:可樂完成后通知我(簡稱通知)。 ② KFC的服務員決定什么時候通知我。 ③ 不止如此,有一天我點了幾個品種想飽餐一頓,結果碰到了一個暈暈的服務員,飯都吃完了也沒有通知我去拿可樂。。。 ④ 無獨有偶,還有一天我點了一懷可樂,竟然先后送了兩杯給我。 ⑤ 即使點餐計劃相同,但環境不同、餐廳不同,最后整個事情的執行過程也不會相同。 ⑥ 點完可樂,我們無需等待,可以選擇做其它的事情。 ⑦ 點完可樂,我們也可以選擇呆呆著等著通知,什么也不做。 ***** ① 在發生調用時,將回調函數(通知)做完參數傳入,形成了一個契約。 ② 被調用者決定什么時候執行回調函數。 ③ 回調函數可以不被執行。 ④ 回調函數可以被執行多次。 ⑤ 同一段包含有回調函數的代碼,每次的執行過程都可能不同。 ⑥ 回調的第一種:異步回調 ⑦ 回調的第二種:同步回調 > 盡管現在生活中充滿著異步。但由于計算機很傻很天真,所以點餐后如果你不主動的告訴它可以去做些別的事情了,那么它就會一直傻傻的等待下去。在JS的世界里,只有在兩種情況下回調是異步的,即:`資源請求`以及`timeout`。在后續的章節中,我們會詳細的介紹。 # 本節小測 有下述代碼: ``` kfc.orderCola(3, function number123(cola: Cola) { ? this.drink(cola); ? }); kfc.orderHamburger(10, function number234(hamburger: Hamburger) { ? this.eat(hamburger); ? } this.playPhone(); ? this.refreshWeibo(); ? ``` 請判斷:以下執行過程是否可能發生: 1. ?????? 2. ?????? 3. ?????? 4. ?????? 5. ?????? 6. ?????? 7. ?????? ## 上節答案 由于以下兩個代碼段等價 ~~~ constructor(private httpClient: HttpClient) { const self = this; /* 向8080端口的helloWorld路徑發起請求 */ this.httpClient.get('http://localhost:8080/helloWorld') .subscribe( function success(data: { message: string }) { this.title = data.message; console.log(data); }, error); } ~~~ ~~~ export class AppComponent { ? constructor(private httpClient: HttpClient) { const self = this; // 常規寫法,避免在回調時發生未知的異常 /* 向8080端口的helloWorld路徑發起請求 */ this.httpClient.get('http://localhost:8080/helloWorld') .subscribe( success, error); } title = 'hello-world'; ? } function success(data: { message: string }) { ? this.title = data.message; ? console.log(data); } ~~~ 我們心中的預期:在?處對?賦值。 實際的執行過程:在?處的`this`位于?中,所以此處的`this`指的是?,并不是?。所以?執行完畢后,?的值并不會發生任何變化。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看