es6學習筆記--promise對象
let promise = new Promise((resolve, reject) =>{ // .... some codingparams:傳參是一個回調函數。這個回調函數有兩個參數resolve和reject。 resolve: 將Promise對象的狀態從“未完成”變為“成功”(即從 pending 變為 resolved),在異步操作成功時調用,並將異步操作的結果,作為參數傳遞出去. (簡單來說就是成功了的執行) reject: 將Promise對象的狀態從“未完成”變為“失敗”(即從 pending 變為 rejected),在異步操作失敗時調用,並將異步操作報出的錯誤,作為參數傳遞出去。 (簡單來說就是失敗了的執行) promise之後then的參數: 第一個參數是成功的回調函數,必選 第二個參數是失敗的回調函數,可選if (true){ // 異步操作成功 resolve(value); } else { reject(error); } }) promise.then(value=>{ // 成功的回調函數 }, error=>{ // 失敗後的回調函數 })
let promise = newPromise((resolve, reject) =>{ console.log(‘開始‘) if (2 > 1){ // 異步操作成功 resolve({name:‘peter‘,age:25}); } else { reject(error); } }) promise.then(value=>{ // 成功的回調函數 console.log(value) }, error=>{ // 失敗後的回調函數 console.log(error) }) // 開始 // {name: "peter", age: 25}
let promise = new Promise((resolve, reject) =>{ console.log(‘開始‘) if (2 > 3){ // 異步操作成功 resolve(a); } else { reject(‘未知錯誤‘); } }) promise.then(value=>{ // 成功的回調函數 console.log(value) }, error=>{ // 失敗後的回調函數 console.log(error) }) // 開始 // 未知錯誤
Promise的特點:
1 對象的狀態不受外界影響。Promise對象代表一個異步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。 2 一旦狀態改變,就不會再變,任何時候都可以得到這個結果。就是成功了就一直是成功的狀態,失敗一直是失敗的狀態promise先按順序實行完promise實例中方法再實行then中的resolve或者reject.
let promise = new Promise((resolve, reject)=>{ console.log(‘promise‘) if (2 > 1){ // 異步操作成功 resolve({name:‘peter‘,age:25}); } else { reject(error); } console.log(‘end‘) }) promise.then( value=>{ console.log(value) }, error=>{ console.log(error) } ) // promise // end // {name: "peter", age: 25}
promise封裝Ajax的例子
const getJSON = function (url) { const promise = new Promise(function (resolve, reject) { const handler = function () { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; const client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); }); return promise; }; getJSON("xxxxx").then(function (json) { console.log(‘Contents: ‘ + json); }, function (error) { console.error(‘出錯了‘, error); });Promise方法:
then() 為 Promise 實例添加狀態改變時的回調函數 ,上面已經提起過.
params: 第一個參數是resolved狀態的回調函數, 必選 第二個參數是rejected狀態的回調函數, 可選 ps: then方法返回的是一個新的Promise實例(註意,不是原來那個Promise實例)。因此可以采用鏈式寫法,即then方法後面再調用另一個then方法。function start() { return new Promise((resolve, reject) => { resolve(‘start‘); }); } start() .then(data => { // promise start console.log(data); return Promise.resolve(1); // p1 }) .then(data => { // promise p1 console.log(data); }) // start // 1
promise的鏈式編程,就是第一個的Promise實例的返回的值作為下一個Promise實例的參數。
catch() 用於指定發生錯誤時的回調函數 和then一樣,存在鏈式
返回一個Promise對象,如果該對象狀態變為resolved,則會調用then方法指定的回調函數;如果異步操作拋出錯誤,狀態就會變為rejected,就會調用catch方法指定的回調函數,處理這個錯誤。function start() { return new Promise((resolve, reject) => { resolve(‘start‘); }); } start() .then(data => { // promise start console.log(data); return Promise.reject(1); // p1 }) .catch(data => { // promise p1 console.log(data); })
ps:then方法指定的回調函數,如果運行中拋出錯誤(reject),也會被catch方法捕獲。如果運行中是正確的,則不會實行catch語句,而是then的回調
function start() { return new Promise((resolve, reject) => { if(2>3){ resolve(‘start‘); }else{ reject(‘error‘) } }); } start() .then(data => { console.log(data); }) .catch(data => { console.log(data); }) // error
try catch方法等價於promise 拋出錯誤:
// 寫法一 const promise = new Promise(function(resolve, reject) { try { throw new Error(‘test‘); } catch(e) { reject(e); } }); promise.catch(function(error) { console.log(error); }); // 寫法二 const promise = new Promise(function(resolve, reject) { reject(new Error(‘test‘)); }); promise.catch(function(error) { console.log(error); })如果鏈式中,寫了then和catch語句,運行正確,則會進行下一個then,在這個then中運行錯誤,則會拋出這個之後的catch而不是上一個catch
function start() { return new Promise((resolve, reject) => { if(4>3){ resolve(‘start‘); }else{ reject(‘error‘) } }); } start() .then(data => { console.log(data); return Promise.resolve(1) }) .catch(data => { console.log(data) }) .then(data => { console.log(data) return Promise.reject(2) }) .catch(data => { console.log(data); }) // start // 1 // 2
finally() 不管promise最後的狀態,在執行完then或catch指定的回調函數以後,都會執行finally方法指定的回調函數
finally方法不接受任何回調函數作為參數,因此不知道Promise對象是resolve還是reject。該方法與Promise狀態無關,不依賴其執行結果。function promise(){ return new Promise((resolve, reject) => { resolve(‘success‘); }) }; promise().then(data => { console.log(data) return Promise.reject(‘fail‘) }).catch(data =>{ console.log(data) }).finally(() => { console.log(‘end‘) }) // success // fail // end
Promise.all() 將多個 Promise 實例,包裝成一個新的 Promise 實例。並行執行異步操作的能力,並且在所有異步操作執行完後才執行回調
const allPromise = Promise.all([p1, p2, p3])上述代表將p1,p2,p3這些Promise實例包裝成allPromise,參數不一定是數組,只要是有遍歷結構就可以作為參數。 從而該實例的狀態有兩種情況: 1: 當所有的狀態都是resolve時,allPromise的狀態是resolve 2:當有一個狀態是reject,allPromise的狀態取決於第一次reject的狀態。 當全部狀態為resolve時。
function promise(){ return new Promise((resolve, reject) => { console.log(1) resolve(‘第一個‘); }) }; function promise1(){ return new Promise((resolve, reject) => { console.log(2) resolve(‘第二個‘); }) }; function promise2(){ return new Promise((resolve, reject) => { console.log(3) resolve(‘第三個‘); }) }; Promise.all([promise(), promise1(), promise2()]) .then(data => { console.log(data) }) .catch(data => { console.log(data) }) // 1 // 2 // 3 // [1,2,3]當全部狀態中有一個是reject時
function promise(){ return new Promise((resolve, reject) => { console.log(1) resolve(‘第一個‘); }) }; function promise1(){ return new Promise((resolve, reject) => { console.log(2) reject(‘第二個‘); }) }; function promise2(){ return new Promise((resolve, reject) => { console.log(3) resolve(‘第三個‘); }) }; Promise.all([promise(), promise1(), promise2()]) .then(data => { console.log(data) }) .catch(data => { console.log(data) }) // 1 // 2 // 3 // 第二個Promise.all()可以適用於初始化的場景
Promise.race() 將多個 Promise 實例,包裝成一個新的 Promise 實例。
和Promise.all()的用法一樣,唯一不同的是,Promise實例中誰先執行,就先返回執行那一方的回調函數(resolve和reject同樣的道理,誰先執行就執行誰的回調函數)function promise(){ return new Promise((resolve, reject) => { setTimeout(function(){ console.log(1); resolve(‘第一個‘); }, 4000); }) }; function promise1(){ return new Promise((resolve, reject) => { setTimeout(function(){ console.log(2); resolve(‘第二個‘); }, 2000); }) }; function promise2(){ return new Promise((resolve, reject) => { setTimeout(function(){ console.log(3); resolve(‘第三個‘); }, 3000); }) }; Promise.race([promise(),promise1(), promise2()]) .then(data => { console.log(data) }) .catch(data => { console.log(data) }) // 2 // 第二個 // 1 // 3該方法可以適用於請求超時觸發回調
Promise.resolve() 返回一個新的Promise實例,並且狀態為resolve。
function fn(){ console.log(‘success‘) return 1 } Promise.resolve(fn()) .then(data => { console.log(data) }) // success // 1
Promise.reject() 返回一個新的Promise實例,並且狀態為reject。
function fn(){ console.log(‘fail‘) return 2 } Promise.reject(fn()) .then(data => { console.log(data) }) .catch(data => { console.log(data) }) // fail // 2
有了Promise
對象,就可以把異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。此外,Promise
對象提供了統一的接口,使得控制異步操作更加容易。
對應的筆記和實例,我放到了GitHub,https://github.com/sqh17/notes
有什麽問題請私信或留下評論,一起加油。
參考資料: 阮一峰大大的es6標準入門:http://es6.ruanyifeng.comes6學習筆記--promise對象