簡單實現非同步編程promise模式_基礎知識

來源:互聯網
上載者:User

非同步編程
javascript非同步編程, web2.0時代比較熱門的編程方式,我們平時碼的時候也或多或少用到,最典型的就是非同步ajax,發送非同步請求,綁定回呼函數,請求響應之後調用指定的回呼函數,沒有阻塞其他代碼的執行。還有像setTimeout方法同樣也是非同步執行回調的方法。

如果對非同步編程還不太熟悉的話,直接戳 阮一峰大牛的教程 ,這篇文章介紹了四種非同步編程的方式:

  1. 回呼函數
  2. 事件監聽
  3. 發布/訂閱
  4. promise模式

這幾種方式的可維護性逐級遞增,理解難度也逐級遞增。這篇總結也是針對promise模式的。

promise模式
那麼多中非同步編程的方式,為什麼選擇promise, 因為前面幾種方式不夠靈活,用起來不夠痛快,不優雅。為了降低非同步編程的複雜性,所以promise。

promise的核心是有一個promise對象,這個對象有一個重要的then()方法, 它用於指定回呼函數,如:

f1().then(f2);

promise模式在任何時刻都有三種狀態:已完成(resolved),未完成(unfulfilled),那麼then()方法就是為狀態變化指定不同的回呼函數,並總是返回一個promise對象,方便鏈式調用。

那promise模式下,返回的資料如何在各個回呼函數之間傳播呢,通過resolve方法,你可以將一個函數的傳回值作為參數傳遞給另一個函數,並且將另一個函數的傳回值作為參數再傳遞給下一個函數……像一條“鏈”一樣無限的這麼做下去。

代碼實現
通過建立一個Promise建構函式來實現promise模式:

//constructorvar Promise = function() { this.callbacks = [];}Promise.prototype = { construct: Promise, resolve: function(result) {  this.complete("resolve", result); }, reject: function(result) {  this.complete("reject", result); }, complete: function(type, result) {  while (this.callbacks[0]) {   this.callbacks.shift()[type](result);  } }, then: function(successHandler, failedHandler) {  this.callbacks.push({   resolve: successHandler,   reject: failedHandler  });  return this; }}// testvar promise = new Promise();var delay1 = function() { setTimeout(function() {  promise.resolve('資料1'); }, 1000); return promise;};var callback1 = function(re) { re = re + '資料2'; console.log(re);};delay1().then(callback1)

程式碼分析
我們可看到一個簡單的promise對象的建構函式的結構:

  • callbacks: 用於管理回呼函數
  • resolve: 請求成功時執行的方法
  • reject:請求失敗時執行的方法
  • complete: 執行回調
  • then:綁定回呼函數

測試:

var promise = new Promise();var delay1 = function() { setTimeout(function() {  promise.resolve('資料1'); }, 1000); return promise;};var callback1 = function(re) { re = re + '資料2'; console.log(re); promise.resolve(re);};var callback2 = function(re) { console.log(re + '資料3');};delay1().then(callback1).then(callback2);

結果:

一秒之後輸出:

分析:

//第一步var delay1 = function() { setTimeout(function() {  promise.resolve('資料1'); }, 1000); return promise;};

這個函數通過setTimeout方法,非同步傳遞一個資料1,並返回一個promise對象(必須)。

//第二步var callback1 = function(re) {  re = re + '資料2'; console.log(re); promise.resolve(re);};

callback1和callback2都是要通過then方法註冊的回呼函數,其中callback1通過resolve方法把資料往下傳遞。

//第三步delay1().then(callback1).then(callback2);

delay1()方法執行完,因為返回了一個promise對象,所以可以再調用then()方法為delay1()的setTimeout非同步執行操作指定回呼函數, 又因為then()方法也返回的是promise對象,所以還可以再調用then方法

//第四步setTimeout(function() { promise.resolve('資料1');}, 1000);

一秒之後,當其他代碼執行完成,開始執行非同步代碼promise.resolve('資料1');,這裡調用promise的resolve()方法,指定了一個成功狀態,並把資料1作為參數。

//第五步resolve: function(result) { this.complete("resolve", result);},//第六步:迴圈執行回調,將上一個回調的結果傳遞給下一個回調complete: function(type, result) { while (this.callbacks[0]) {  this.callbacks.shift()[type](result); }},

這其中比較難理解的就是第五,六步。

以上就是本文的全部內容,希望對大家的學習有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.