1. 程式人生 > >ES6之Promise物件學習——8個例子學會Promise

ES6之Promise物件學習——8個例子學會Promise

目錄

  1. Promise 立即執行
  2. Promise 三種狀態
  3. Promise 不可逆性
  4. 鏈式呼叫
  5. Promise.then()回撥非同步性
  6. Promise中的異常
  7. Promise.resolve()
  8. resolve vs reject

一、Promise立即執行

程式碼:

var p = new Promise(function(resolve, reject){
    console.log('create a promise');
    resolve('success');
});

console.log('after new Promise');

p.then(
    function
(val){
console.log(val); }, function(err){ console.log(err); } )

執行結果:

*   create a promise
*   after new Promise
*   success

解析:

Promise物件表示未來要發生的事情,但是在建立 new Promise(function(){}) 時,其中的匿名函式是會被立即執行的,只是其中的程式碼可以是非同步執行的{ example: 體現在 p.then()會被非同步執行,但是一定要 這樣呼叫一次resolve(‘success’),才會執行p.then()

}。

二、Promise三種狀態

程式碼:

var p1 = new Promise(function(resolve, reject){
    resolve(1);
});

var p2 = new Promise(function(resolve, reject){
    setTimeout(function(){
        resolve(2);
    }, 500);    
});

var p3 = new Promise(function(){
    setTimeout(function(){
        resolve(3);
    }, 500
); }); console.log(p1); console.log(p2); console.log(p3); setTimeout(function(){ console.log(p2); }, 1000); setTimeout(function(){ console.log(p3); }, 1000); p1.then(function(val){ console.log(val); }); p2.then(function(val){ console.log(val); }); //此處的catch方法,等價於then(fn1, fn2)方法中的fn2。 當resolve()時,執行fn1;當reject時,執行fn2。 p3.catch(function(err){ console.log(err); });

執行結果:

Promise { 1 }
Promise { <pending> undefined }
Promise { <pending> undefined }
1
2
3
Promise { <resolved> 2 }
Promise { <rejected> 3 }

解析:

Promise的內部實現是一個狀態機,Promise有3鍾狀態:pending、resolved、rejected。
*當Promise剛剛建立完成時,處於pengding。
*當Promise中的函式執行resolve方法後,由之前的pending –> resolved
*當Promise中的函式不執行resolve,而是執行了reject方法,那會由之前的pending –> rejected

三、Promise 狀態的不可逆性

程式碼:

var p1 = new Promise(function(resolve, reject){
    resolve('success1');
    resolve('success2');
});

var p2 = new Promise(function(resolve, reject){
    resolve('success3');
    reject('reject');   
});

p1.then(function(val){
    console.log(val);
});
p2.then(function(val){
    console.log(val);
});

執行結果:

success1
success

解析:

Promise的狀態一定確定下來時,Promise的狀態和值就固定下來了,不論如何呼叫 resolve()reject() ,都不能改變它的值和狀態。

四、鏈式呼叫

程式碼:

var p = new Promise(function(resolve, reject){
    resolve(1);
});

p.then(     //第1then
    function(val){
        console.log(val);
        return val*2;
    }
).then(     //第2then
    function(val){
        console.log(val);
    }
).then(     //第3then
    function(val){
        console.log(val);
        return Promise.resolve('resolve');
    }
).then(     //第4then
    function(val){
        cosnole.log(val);
        return Promise.reject('reject');
    }
).then(     //第5then
    function(val){
        console.log('resolve=' + val);
    }, function(err){
        console.log('reject=' + err);
    }
);

執行結果:

1
2
undefined
resolve
reject=reject

解析:

Promise物件的then方法返回一個新的Promise物件,因此可以通過鏈式呼叫then方法。then方法接收2個引數,第一個引數是Promise執行成功時的回撥;第二個是Promise執行失敗的回撥。2個函式只有一個被呼叫,函式的返回值將被用作建立then返回的Promise物件,這2個引數的返回值可以是一下3種情況中的一種:
* return 一個同步值 或者 undefined (當沒有一個有效的返回值時,預設返回undefined,then方法將返回一個resolved狀態的Promise物件,Promise物件的值就是這個返回值。)
* return 另一個Promise, then方法將根據這個Promise的狀態和值建立一個新的Promise物件返回。
* throw 一個同步異常,then方法將返回一個rejected狀態的Promise和該異常值。

所以 第一個then返回值是:2;第二個then沒有返回值,預設返回undefined;第三個then會返回一個狀態是resolved值是resolve的新Promise物件;第四個then會返回一個狀態為rejected值為reject的新Promise物件;第五個then因為執行失敗,會走第二個函式。

五、Promise.then()回撥非同步性

程式碼:

var p1 = new Promise(function(resolve, reject){
    resolve('success');
});

p1.then(function(val){
    console.log(val);
});

console.log("which one is called first ?");

執行結果:

which one is called first ?
success

解析:

Promise接收的函式是同步執行的,但是then中的回撥函式的執行則是非同步的。

因此‘sucees’會在後面輸出。

為什麼then會優先於定時器先執行?
*是因為等待佇列(或者說是任務佇列)其實是分為兩個: macrotask 和 microtask;promise是存放在microtasks中,而定時器是存放在macrotasks中,但是在每次”事件迴圈”後會先執行microtask中的內容,並且當這些 microtask 執行結束後還能繼續新增 microtask 一直到真個 microtask 佇列執行結束(這也就是所說的”拆箱”),直到當前microtask執行結束之後,才會執行macrotask中的任務,並且往下進行”事件迴圈”所以才會出現如上程式碼輸出的結果。

六、Promise中的異常

程式碼:

var p1 = new Promise(function(resolve, reject){
    foo.bar();//異常執行
    resolve(1);
});

p1.then(
    function(val){
        console.log('p1 then val:' + val);
    }, function(err){
        console.log('p1 then err:' + val);
    }
).then(
    function(val){
        console.log('p1 then val:' + val);
    }, function(err){
        console.log('p1 then err:' + val);
    }
);

var p2 = new Promise(function(resolve, reject){
    resolve(2);
});

p2.then(
    function(val){
        console.log('p2 then val:' + val);
        foo.bar();//異常執行
    }, function(err){
        console.log('p2 then err:' + val);
    }
).then(
    function(val){
        console.log('p2 then val:' + val);
    }, function(err){
        console.log('p2 then err:' + val);
        return 1;
    }
).then(
    function(val){
        console.log('p2 then val:' + val);
    }, function(err){
        console.log('p2 then err:' + val);
    }
);

執行結果:

p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then value: undefined
p2 then err: ReferenceError: foo is not defined
p2 then value: 1

解析:

Promise中的異常有then引數中的第二個回撥函式 (Promise執行失敗的回撥) 處理,異常資訊作為Promise的值。異常一旦得到處理, then後返回的後續Promise物件恢復正常,並會被Promise執行成功的回撥函式處理。 另外需要注意:p1、p2多級then的回撥函式是交替執行的,這正是由於Promise then回撥的非同步性決定的。

七、Promise中的異常

程式碼:

var p1 = Promise.resolve(1);
var p2 = Promise.resolve(p1);
var p3 = new Promise(function(resolve, reject){
    resolve(1);
});
var p4 = new Promise(function(resolve, reject){
    resolve(p1);
});

console.log( p1 === p2 );
console.log( p1 === p3 );
console.log( p1 === p4 );
console.log( p3 === p4 );

p4.then(function(val){
    console.log('p4=' + val);
});

p2.then(function(val){
    console.log('p2=' + val);
});

p1.then(function(val){
    console.log('p1=' + val);
});

執行結果:

true
false
false
false
p2=1
p1=1
p4=1

解析:
Promise.resolve(…)可以接收一個值或者是一個Promise物件作為引數。
* 當引數為普通值時,他返回一個resolved狀態的Promise物件,物件的值就是這個引數。
* 當引數為一個Promise物件時,會直接返回這個Promise物件。
* 使用new建立的Promise物件是一個全新的物件。
所以p1===p2,所以p1不等於p3,p4。
p4之所以是最先呼叫最後輸出是因為:
p4接收的是一個promise物件p1,resolve會對p1進行’拆箱’,獲取p1的值。

八.resolve vs reject

程式碼:

var p1 = new Promise(function(resolve, reject){
    resolve(Promise.resolve('resolve'));
});

var p2 = new Promise(function(resolve, reject){
    resolve(Promise.reject('reject'));
});

var p3 = new Promise(function(resolve, reject){
    reject(Promise.resolve('resolve'));
});


p1.then(
        function(val){
            console.log('p3[val]=' + val );
        },
        function(err){
            console.log('p3[err]=' + err ); 
        }
    )

p2.then(
        function(val){
            console.log('p3[val]=' + val );
        },
        function(err){
            console.log('p3[err]=' + err ); 
        }
    )

p3.then(
        function(val){
            console.log('p3[val]=' + val );
        },
        function(err){
            console.log('p3[err]=' + err ); 
        }
    )

執行結果:

*   p3[err]=[object Promise]
*   p3[val]=resolve
*   p3[err]=reject

解析:
* resolve 可以’拆箱’Promise物件; reject不能’拆箱’Promise物件。

相關推薦

ES6Promise物件學習——8例子學會Promise

目錄 Promise 立即執行 Promise 三種狀態 Promise 不可逆性 鏈式呼叫 Promise.then()回撥非同步性 Promise中的異常 Promise.resolve() resolve vs reject 一、Promise

學習筆記:es6——Promise 物件學習(1)

1Promise的含義: Promise是非同步程式設計的一種解決方案; Promise是一個物件,可以獲取非同步操作的訊息,提供統一的api,各種非同步操作都可以用同樣的方式處理; Promise物件有以下兩個特點: 物件狀態不受外界影響。Promise代表

JavaScript面向物件學習筆記

JavaScript物件 將相關的變數和函式組合成一個整體,這個整體叫物件,物件中的變數叫做屬性,變數中的函式叫做方法。 JavaScript建立物件的方法 1、單體模式 2、工廠模式 <script type="text/javascript"> functi

ES6擴充套件物件的功能性

目錄 一、物件類別 二、物件字面量的語法擴充套件 2.1、屬性初始值的簡寫 2.2、物件方法的簡寫語法 2.3、可計算屬性名 三、新增方法 3.1、Object.is()方法 3.2、Object.assign()方法 四、重複的物件字面量屬性 五、自有屬性列

promise 物件的兩特點

物件的狀態不受外界影響。Promise物件代表一個非同步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有非同步操作的結果,可以決定當前是哪

黑馬程式設計師 java程式設計面向物件學習筆記

---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ----------------------面向物件:以前學習過C語言,C語言是面向過程,裡面功能的實現都是由呼叫一個個的函式來完成的,而java是面向物件的程式語

黑馬程式設計師 java程式設計面向物件學習筆記總結

---------------------- ASP.Net+Unity開發、.Net培訓、期待與您交流! ---------------------- 繼承: 在java中,在我們要對一個事物進行封裝時,發現有某一個類的特性和要封裝的這個 類的特性相同,而我們可以在這個

一個簡單的例子搞懂ES6Promise

準備工作 實現 查看 AS spa div 原理 事件 例子 ES5中實現異步的常見方式不外乎以下幾種: 1. 回調函數 2. 事件驅動 2. 自定義事件(根本上原理同事件驅動相同) 而ES6中的Promise的出現就使得異步變得非常簡單。promise中的異步是這

ES6學習路上的小學生,promise處理非同步操作,簡易原始起步用。先能用,再深究!

ES6的promise物件,讓我們更容易的處理這樣的需求:執行完一個方法以後,再去執行下一個方法。 理解尚淺之時,先用於專案之中。 1 var promise1 = new Promise(function(resolve, reject) { 2 //

ES6學習路上的小學生,promise處理異步操作,簡易原始起步用。先能用,再深究!

接收 class 異步操作 簡單的 小學生 resolv ces 後置 小學 ES6的promise對象,讓我們更容易的處理這樣的需求:執行完一個方法以後,再去執行下一個方法。 理解尚淺之時,先用於項目之中。 1 var promise1 = new P

ES6 Promise物件例項方法(2)

ES6 Promise物件之例項方法(2) 上一篇關於Promise的文章介紹了Promise的基本用法,這一篇繼續上一篇,介紹Promise的各種方法: (1)Promise.prototype.then() then方法是定義在原型物件Promise.prototype上的。

ES6Promise物件

首先,文章內容基本來自ECMAScript 6 入門(作者 阮一峰) 簡介 Promise物件是非同步程式設計的一種解決方案。所謂Promise,簡單來說就是一種容器,裡面包含著未來可能結束的一個事件的結果。 Promise包含三種狀態,pending,f

ES6Promise 物件

含義 Promise是非同步程式設計的一種解決方案,比回撥函式和事件這兩個傳統的解決方案更合理更強大。 是一個容器,存放著某個未來才會結束的事件(通常是一個非同步操作)結果。從語義上說,Promise是一個物件,可以獲取非同步操作的資訊。提供統一的API,各種非同步操作都可以同樣

Qt 學習之路 2(19):事件的接受與忽略(當重寫事件回撥函式時,時刻注意是否需要通過呼叫父類的同名函式來確保原有實現仍能進行!有好幾個例子。為什麼要這麼做?而不是自己去手動呼叫這兩函式呢?因為我們無法確認父類中的這個處理函式有沒有額外的操作)

版本: 2012-09-29 2013-04-23 更新有關accept()和ignore()函式的相關內容。 2013-12-02 增加有關accept()和ignore()函式的示例。 上一章我們介紹了有關事件的相關內容。我們曾經提到,事件可以依情況接受和忽略。現在,我們就

ES6學習面向物件

1.寫法 class User{ constructor(name,password){//構造器 this.name = name; this.password = password;

ES6Promise學習與實踐

1.前言   在平時的業務開發中,前端通常需要請求後臺獲取資料,或者NodeJs讀取檔案等等一系列的非同步操作,我們通常需要利用非同步操作的結果或者對非同步操作的結果進行處理。通常我們的解決方案是:在非同步操作成功或者失敗的回撥函式裡面寫方法,在非同步操作比較簡單的時候這樣寫程式碼還是比較好理解的,當業務逐

ES6入門Promise物件

1. Promise 的含義 Promise 是非同步程式設計的一種解決方案,比傳統的解決方案--回撥函式和事件更合理、更強大。 1.1 什麼是Promise 簡單來說就是一個容器,裡面儲存著某個未來才會結束的事件(也就是非同步操作)的結果。從語法上來講,Promise是一個物件,從它可以獲取非同步

學習es6(變量的解構賦值)

返回 blog 成了 所在 asc 對象 expected 正弦 peer 數組的解構賦值 ES6允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構。 以前,為變量賦值,只能直接指定值。 let a = 1; let b = 2; let c = 3;

一、WCF學習旅-創建第一服務

img image pub 頁面 添加服務 ets art idt null WCF基本介紹:http://baike.baidu.com/link?url=TGjLYt3HS4dt4-hIiGRknLy6udRsZ52QxJz9cmRKlR4NXbP9rCZDsKn2fD

libevent學習,從3例子開始

dispatch 引用 復雜 printf tin details serve fin reply 最近一直在ubuntu下研究c++開源代碼,本文的內容是大名鼎鼎的libevent庫。 本文將從3個例子著手,從簡單到復雜,分別包含了client與server。 文章參考該