Javascript語言的執行環境是"單線程"(single thread)。所謂"單線程",就是指一次只能完成一件任務。若是有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。這種模式的好處是實現起來比較簡單,執行環境相對單純;壞處是隻要有一個任務耗時很長,後面的任務都必須排隊等着,會拖延整個程序的執行。常見的瀏覽器無響應(假死),每每就是由於某一段Javascript代碼長時間運行(好比死循環),致使整個頁面卡在這個地方,其餘任務沒法執行。爲了解決這個問題,Javascript語言將任務的執行模式分紅兩種:同步(Synchronous)和異步(Asynchronous)。"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,而後再執行,程序的執行順序與任務的排列順序是一致的、同步的;"異步模式"則徹底不一樣,每個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,因此程序的執行順序與任務的排列順序是不一致的、異步的。"異步模式"很是重要。在瀏覽器端,耗時很長的操做都應該異步執行,避免瀏覽器失去響應,最好的例子就是Ajax操做。在服務器端,"異步模式"甚至是惟一的模式,由於執行環境是單線程的,若是容許同步執行全部http請求,服務器性能會急劇降低,很快就會失去響應。編程
例如:有兩個函數 f1() 和 f2(); 若是是promise
f1();瀏覽器
f2();服務器
那麼f2()要等到f1() 執行完了才能執行。這樣要是f1執行時間很長 那麼f2就等好久,這樣子就會形成假死現象。咱們能夠把f2寫成f1的構造函數。
異步
咱們把同步操做變成了異步操做,f1不會堵塞程序運行,至關於先執行程序的主要邏輯,將耗時的操做推遲執行。回調函數的優勢是簡單、容易理解和部署,缺點是不利於代碼的閱讀和維護,各個部分之間高度耦合(Coupling),流程會很混亂,並且每一個任務只能指定一個回調函數。異步編程
另外一種思路是採用事件驅動模式。任務的執行不取決於代碼的順序,而取決於某個事件是否發生。函數
什麼是Promises?性能
首先,它是一個對象,也就是說與其餘JavaScript對象的用法,沒有什麼兩樣;其次,它起到代理做用(proxy),充當異步操做與回調函數之間的中介。它使得異步操做具有同步操做的接口,使得程序具有正常的同步運行的流程,回調函數沒必要再一層層嵌套。簡單說,它的思想是,每個異步任務馬上返回一個Promise對象,因爲是馬上返回,因此能夠採用同步操做的流程。這個Promises對象有一個then方法,容許指定回調函數,在異步任務完成後調用。spa
好比,異步操做f1
返回一個Promise對象,它的回調函數f2
寫法以下。線程
(new Promise(f1)).then(f2);
Promise接口的基本思想是,異步任務返回一個Promise對象。對象的三種狀態。
三種的狀態的變化途徑只有兩種。
這種變化只能發生一次,一旦當前狀態變爲「已完成」或「失敗」,就意味着不會再有新的狀態變化了。所以,Promise對象的最終結果只有兩種。
Promise對象使用then
方法添加回調函數。then
方法能夠接受兩個回調函數,第一個是異步操做成功時(變爲resolved
狀態)時的回調函數,第二個是異步操做失敗(變爲rejected
)時的回調函數(能夠省略)。一旦狀態改變,就調用相應的回調函數。
我這裏先說到這裏寫一個簡單的Promise對象
var promise = new Promise(function(resolver,reject){
});
下一篇先說說異步編程 promise遇到的問題 和promise的實現 和方法使用。
//非函數式 var title = "Functional Programming"; var saying = "This is not"; console.log(title + saying); //函數式 var say = function(title){ return "This is" + title; }; var text = say("Function Programming"); //純函數 // 指的是函數內外間無關聯的 // A) 沒有反作用 不會涉及到外部變量的使用或修改 // B) 引用透明 函數內只會依賴傳入參數 在任什麼時候候對函數輸入相同的參數時。 //柯里化 是將多參函數 轉換成一系列的單參函數 var add = (a,b) => a + b; var add = function(a,b){ return a + b; }; var add = function(a){ return function (b){ return a + b; }; }; console.log(add(1)(2)); //可變數據(immutable) var arr = ["Functional", "Programming"]; arr[0] = "Other"; // <= 修改了arr[0]的值 console.log(arr); // ["Other","Programming"] //獲得新的變量 不修改了原來的值 var arr = ["Functional", "Programming"]; var newArr = arr.map(function(item){ if(item === "Functional"){ return "Other"; }else{ return item; } }); console.log(arr); //["Functional","Programming"] console.log(newArr); //["Other", "Programming"] //組合函數 var compose = (fn1,fn2) => (arg) => fn1(fn2(arg)); var compose = function(fn1,fn2){ return function(arg){ return fn1(fn2(arg)) } }