程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> ES6新特性之 promise,es6新特性promise

ES6新特性之 promise,es6新特性promise

編輯:關於.NET

ES6新特性之 promise,es6新特性promise


  新的ES6中引入了promise的概念,目的是讓回調更為優雅。層層嵌套的回調會讓javascript失去美感和可讀性,同時javascript也推薦采用鏈式的方式去書寫函數調用。於是Promise就應運而生。Promise即承諾的意思,new一個Promise就是新建一個承諾。在新建一個承諾的時候你需要做兩件事情:

  1.指定承諾所需完成的事

  2.設置承諾是否實現的標准

下面我們來定義一個承諾:

  1.承諾的內容:“獲取data.php的數據”,

  2.承諾是否實現的評判是:是否獲取data.php的數據 ”

這裡我們會用到jQuery.ajax()方法,這會讓我們的代碼顯得簡單精煉。

var http = {
    get: function(url) {
        var promise = new Promise(function(resolve, reject) {
            $.ajax({
                url: url,
                method: 'get',
                success: function(data) {
                    resolve(data);
                },
                error: function(xhr, statusText) {
                    reject(statusText);
                }
            });
        });
        return promise;
    }
};
http.get('data.php').then(function(data) {
    document.write(data);
}, function(err) {
    document.write(err);
});

  這裡是獲取的data值

/* data.php文件 */
<?php
echo '{"name":"Tom","age":"22"}';

  在http請求中,我們定義了一個get方法,在get方法中,我們定義了一個promise的對象,而不是直接直接使用ajax獲取到我們想要的數據,在這個get方法,我們最後得到的是一個promise對象,對於這種需要等待的操作,我們采用promise去處理,返回給主線程的是一個promise對象,而不是一個最終的數據,這是延遲程序給主程序的一個承諾,主線程可以根據通過返回的promise對象獲取數據或者處理錯誤。這使得異步處理變得優雅而簡單。

  在jQuery.ajax()中,我們采用了兩個方法來判斷是否實現了我們的承諾,它們分別是resove和reject方法,如果如果jQuery.ajax()執行了success,並且返回的data中有數據,那麼我們就判定這個承諾已經實現了(fulfilled),則調用resolve方法。如果jQuery.ajax()執行了error,那麼我們就判定這個承諾被拒絕了(rejected),則調用reject方法。

那resove和reject這兩個方法分別執行了哪些操作呢?這個我們就需要從Promise這個構造函數本身的結構說起。Promise這個構造函數結構大概是下面這樣的:

/* 用於描述思維的代碼 */
function Promise(executor) {
    // 共有三種狀態:pending(准備)、fulfilled(完成)、rejected(拒絕)
    this.PromiseStatus = 'pending';
    // 用於存儲返回的數據
    this.PromiseValue;
    // 完成
    var resolve = function(reson) {};
    // 拒絕
    var reject = function(reson) {};
    ...
    // 開始執行承諾
    executor(resolve, reject);
}
Promise.prototype.then = function() {};
Promise.prototype.chain = function() {};
Promise.prototype.catch = function() {};
...

  

PromiseStatus:用於記錄Promise對象的三種狀態,這三中狀態分別是:
pending:待定狀態,Promise對象剛被初始化的狀態
fulfilled:完成狀態,承諾被完成了的狀態
rejected:拒絕狀態,承諾完成失敗的狀態
Promise的初始狀態是pending。隨後會更具承諾完成的情況更改PromiseStatus的值。

PromiseStatus:用於記錄返回的數據或者錯誤。當承諾完成時,會把返回的數據賦給PromiseStatus。如果承諾執行失敗了,那麼失敗的原因也會賦給此變量。

resolve()和reject():Promise構造函數中有兩個閉包的函數resolve()和reject()。在new一個新的Promise的時候會傳遞一件你需要做的事情(executor)。這個executor是一個函數,在Promise的構造函數中它會被傳入兩個參數,這兩個參數即我們的兩個閉包的函數resolve()和reject(),以便你在executor中判定是否完成了你的承諾。

executor(): executor()函數中執行的代碼就是子程序需要完成事。在executor()函數內如果調用了resolve(),resolve()則會把Promise對象的狀態PromiseStatus修改為fulfilled,把resolve(value)中的value值賦給Promise對象的PromiseValue。然後再依次執行由then()方法構成的回調鏈中的回調函數。同樣,在executor()中調用reject()的過程也是類似的。調用過程如下:



/* 用於描述思維的代碼 */
executor(resolve, reject) {
    ...
    resolve(value);
    ...
}
...
resolve(value) {
    PromiseStatus = 'fulfilled';
    PromiseValue = value;
    ...
    // 接著調用回調鏈中的回調函數
}

  

then(onFulfilled, onRejected):這個方法實際上是把onFulfilled()函數和onRejected()函數添加到Promise對象的回調鏈中。回調鏈就像一個由函數組構成的隊列,每一組函數都是由至少一個函數構成(onFulfilled() 或者 onRejected() 或者 onFulfilled() 和 onRejected())。當resolve()或者reject()方法執行的時候,回調鏈中的回調函數會根據PromiseStatus的狀態情況而被依次調用。

onFulfilled(value)和onRejected(reason):參數value和reason的實參都是PromiseValue。這裡有一點值得注意,如果onFulfilled(value)和onRejected(reason)這兩個回調函數中return返回值不是一個Promise的對象,那麼這個返回值會被賦給PromiseValue,並在下一個then()的onFulfilled(value)和onRejected(reason)中做為實參使用。但如果這個返回值是一個Promise的對象,那麼剩下的由then()構造的回調鏈會轉交給新的Promise對象並完成調用。

有這樣一個問題,如果在第一個then()中執行了onRejected(reason)回調函數,並且沒有return任何值的時候,那麼下一個then()中將會調用onFulfilled(value)方法,而不是onRejected(reason)。因為在執行上一個then()的onRejected(reason)回調函數的時候並沒有出現錯誤或異常,所以PromiseStatus的狀態就被更改為fulfilled了。為了避免這個問題,我們可以在onRejected(reson)中返回一個Promise對象並reject()。代碼如下,我們要去訪問一個並不存在的文件solve.php:

var http = {
    get: function(url) {
        var promise = new Promise(function(resolve, reject) {
            $.ajax({
                url: url,
                method: 'get',
                success: function(data) {
                    resolve(data);
                },
                error: function(xhr, statusText) {
                    reject(statusText);
                }
            });
        });
        return promise;
    }
};
http.get('solve.php').then(function(data) {
    return data;
}, function(err) {
    return Promise.reject('Sorry, file not Found.');
}).then(function(data) {
    document.write(data);
}, function(err) {
    document.write(err);
});

  Promise.reject()方法會返回一個被reject()的Promise對象,因此使得我們可以繼續走下一個then()中的onRejected(reason)方法。

 

這個是對於promise的一些終結,參考了道友們的思考,原文鏈接:http://www.jianshu.com/p/87183851756f

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved