天天看點

JavaScript異步程式設計1——Promise的初步使用

javascript異步程式設計1——promise的初步使用

目錄

1. 概述

2. 詳論

3. 參考

promise對象是es6提出的的異步程式設計的規範。說到異步程式設計,就不得不說說同步和異步這兩個概念。

從字面意思了解同步程式設計的話,似乎指的是兩個任務同步運作,如果這樣了解就錯了(至少筆者再沒有接觸到這個概念的時候有這種誤解)。同步和異步指的是代碼指定執行的順序(結構化程式設計範式的執行順序總是由上至下,由前往後的),如果執行的順序與代碼的相同,就是同步;如果不同,就是異步。

最初,作業系統都是基于指令行的,所有的的語言設計出來也天然是同步的語句,在這種情況下,也不需要異步程式設計。但是很快,圖形操作界面就出來了,所有的程式設計語言都不得不跟gui打交道了。我們必須了解的是,gui程式是一個不停繪制的界面程式:

如果每個循環中執行的任務dosomething()的事件太長,就會導緻界面遲遲得不到繪制指令,直覺的表現就是卡頓。為了解決這個問題,使用javascript作為腳本的浏覽器一般都會采用事件循環(event loop)的機制:

将耗時的行為規定為事件,事件與響應回調函數綁定。

每個循環,優先處理同步代碼。

同步代碼完成,按照先後順序周遊事件。

在剩下的沒有同步代碼的循環中,依次執行事件的相應函數。

這樣,在單線程的情況下,就修改了任務的執行順序,實作了異步的機制。因為同步的行為總是很快完成及時進行了界面繪制,界面卡頓的現象也大為改善了。

事件循環機制将ui裝置的輸入輸出規定為事件,實際上,耗時的行為非常多,但是一般都與io相關,與io相關的行為,javascript都提供了異步行為的代碼。例如,這裡要用的一個加載圖檔的執行個體。

首先準備一個html頁面promisetest.html,在這個html頁面中加載js的腳本promisetest.js:

原生的js的圖像對象image,是通過事件的形式來實作圖像的異步加載的:

為image的事件句柄onload,添加一個相應函數,當圖像裝載完成之後,就将裝載好的image添加到html頁面的某個div元素子節點下。通過浏覽器打開這個頁面,會直接顯示對應位址的圖檔。

這個js腳本當然也可以通過promise來改寫:

粗看起來,使用promise,似乎使得程式顯得更加複雜和繁複了。但是我們要深入了解promise機制的内涵,這樣設計并不是為了好玩。

promise對象代表的是一個預定要做、但是還未開始做的行為。既然是一個行為,當然得進行計劃,并對行為結果做出規定:如果成功了,就執行resolve;如果失敗了,就執行reject。一般我們可以定義一個function,并且傳回一個promise對象。

調用傳回promise對象的function,這樣這個想要進行的行為就真正啟動了。不過resolve和reject隻是兩個回調函數,那麼就通過then方法來規定成功和失敗對應的真正的處理函數。

可以看到,這樣的設計看起來很繁複,但是卻很像是一個同步行為:規定一個未完成行為對象,行為完成了如何處理,行為失敗了又如何處理。而這也是promise的目的:使得異步操作更像是一個同步的行為。

同步(synchronous)和異步(asynchronous)

簡述js單線程異步實作原理

javascript 運作機制詳解:再談event loop

繼續閱讀