国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript中Promise的使用詳解

2019-11-19 17:25:05
字體:
來源:轉載
供稿:網友

Promise是ES6中的函數,規范了如何處理異步任務的回調函數,功能類似于jQuery的defferred。簡單說就是通過promise對象的不同狀態調用不同的回調函數。目前IE8及以下不支持,其他瀏覽器都支持。

promise對象的狀態,從Pending轉換為Resolved或Rejected之后,這個promise對象的狀態就不會再發生任何變化。

使用步驟:

var promise = new Promise(function(resolve, reject) { // 異步任務,通過調用resolve(value) 或 reject(error),以改變promise對象的狀態;改變狀態的方法只能在此調用。//promise狀態改變后,會調用對應的回調方法});promise.then(function(value){//resolve時的回調函數,參數由異步的函數傳進來}).catch(function(error){//發生異常時或明確reject()時的回調函數})

 具體使用:

function getURL(URL) {           //因為promise創建時即執行,所以用工廠函數封裝promise對象  return new Promise(function (resolve, reject) {    var req = new XMLHttpRequest();    req.open('GET', URL, true);    req.onload = function () {      if (req.status === 200) {        resolve(req.responseText);      } else {        reject(new Error(req.statusText));      }    };    req.onerror = function () {      reject(new Error(req.statusText));    };    req.send();  });}// 運行示例var URL = "http://httpbin.org/get";getURL(URL).then(function onFulfilled(value){  console.log(value);}).catch(function onRejected(error){  console.error(error);});

Promise的回調只有異步方式,即使是同步任務的回調也是異步執行 。

var promise = new Promise(function (resolve){  console.log("inner promise");         // 執行1:同步任務先執行  resolve(‘callBack');});promise.then(function(value){  console.log(value);              // 執行3:雖然注冊時狀態為resolved,但回調仍是異步的;});console.log("outer promise");          // 執行2:同步代碼先執行


 

promise的方法鏈

then方法注冊的回調會依次被調用,每個then方法之間通過return 返回值傳遞參數。但是回調中的異常會導致跳過之間then的回調,直接調用catch的回調,之后再繼續調用剩下的then的回調。在then(onFulfilled, onRejected)中,onFulfilled的異常不會被自己的onRejected捕獲,所以優先使用catch。

 promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask);

 taskA拋異常,taskB被跳過,finalTask仍會被調用,因為catch返回的promise對象的狀態為resolved。

then方法內可以返回3種值

1. 返回另一個promise對象,下一個then方法根據其狀態選擇onFullfilled/onRejected回調函數執行,參數仍由新promise的resolv/reject方法傳遞;

2. 返回一個同步值,下一個then方法沿用當前promise對象的狀態,無需等異步任務結束會立即執行;實參為上一then的返回值;如果沒有return,則默認返回undefined;

3. 拋出異常(同步/異步):throw new Error(‘xxx');

then不僅是注冊一個回調函數,還會將回調函數的返回值進行變換,創建并返回一個新promise對象。實際上Promise在方法鏈中的操作的都不是同一個promise對象。

var aPromise = new Promise(function (resolve) {  resolve(100);});var thenPromise = aPromise.then(function (value) {  console.log(value);});var catchPromise = thenPromise.catch(function (error) {  console.error(error);});console.log(aPromise !== thenPromise); // => trueconsole.log(thenPromise !== catchPromise);// => true

Promise.all()靜態方法,同時進行多個異步任務。在接收到的所有promise對象都變為FulFilled 或者Rejected 狀態之后才會繼續進行后面的處理。

Promise.all([promiseA, promiseB]).then(function(results){//results是個數組,元素值和前面promises對象對應});// 由promise對象組成的數組會同時執行,而不是一個一個順序執行,開始時間基本相同。function timerPromisefy(delay) {  console.log('開始時間:”'+Date.now())   return new Promise(function (resolve) {    setTimeout(function () {      resolve(delay);    }, delay);  });}var startDate = Date.now();Promise.all([  timerPromisefy(100),    //promise用工廠形式包裝一下  timerPromisefy(200),  timerPromisefy(300),  timerPromisefy(400)]).then(function (values) {  console.log(values);  // [100,200,300,400]});

不同時執行,而是一個接著一個執行promise

//promise factories返回promise對象,只有當前異步任務結束時才執行下一個thenfunction sequentialize(promiseFactories) {  var chain = Promise.resolve();  promiseFactories.forEach(function (promiseFactory) {    chain = chain.then(promiseFactory);  });  return chain;}

Promise.race()同all()類似,但是race()只要有一個promise對象進入 FulFilled 或者 Rejected 狀態的話,就會執行對應的回調函數。不過在第一個promise對象變為Fulfilled之后,并不影響其他promise對象的繼續執行。

//沿用Promise.all()的例子Promise.race([  timerPromisefy(1),  timerPromisefy(32),  timerPromisefy(64),  timerPromisefy(128)]).then(function (value) {  console.log(values);  // [1]});

Promise.race()作為定時器的妙用

Promise.race([  new Promise(function (resolve, reject) {    setTimeout(reject, 5000);     // timeout after 5 secs  }),  doSomethingThatMayTakeAwhile()]);  

在then中改變promise狀態

因為then的回調中只有value參數,沒有改變狀態的方法(只能在構造方法的異步任務中使用),要想改變傳給下一個then的promise對象的狀態,只能重新new一個新的Promise對象,在異步任務中判斷是否改變狀態,最后return出去傳給下一個then/catch。

var promise = Promise.resolve(‘xxx');//創建promise對象的簡介方法promise.then(function (value) {  var pms=new Promise(function(resolve,reject){    setTimeout(function () {      // 在此可以判斷是否改變狀態reject/resolve      Reject(‘args');    }, 1000);  })  return pms;  //該promise對象可以具有新狀態,下一個then/catch需要等異步結束才會執行回調;如果返回普通值/undefined,之后的then/catch會立即執行}).catch(function (error) {  // 被reject時調用  console.log(error)});        

獲取兩個promises的結果

//方法1:通過在外層的變量傳遞var user;getUserByName('nolan').then(function (result) {  user = result;  return getUserAccountById(user.id);}).then(function (userAccount) {  //可以訪問user和userAccount});//方法2:后一個then方法提到前一個回調中getUserByName('nolan').then(function (user) {  return getUserAccountById(user.id).then(function (userAccount) {    //可以訪問user和userAccount  });});


 

注意使用promise時的整體結構

假定doSomething()和doSomethingElse()都返回了promise對象

常用方式:

doSomething().then(doSomethingElse).then(finalHandler);doSomething|-----------------|         doSomethingElse(resultOfDoSomething)  //返回新promise,下一個then要收到新狀態才執行         |------------------|                   finalHandler(resultOfDoSomethingElse)                   |---------------------|

常用變通方式:

doSomething().then(function () { return doSomethingElse();}).then(finalHandler);doSomething|-----------------|         doSomethingElse(undefined) //then外層函數的arguments[0]== resultOfDoSomething         |------------------|                   finalHandler(resultOfDoSomethingElse)                   |------------------| 

錯誤方式1:

doSomething().then(function () { doSomethingElse();}).then(finalHandler);doSomething|-----------------|         doSomethingElse(undefined)  //雖然doSomethingElse會返回promise對象,但最外層的回調函數是return undefined,所以下一個then方法無需等待新promise的狀態,會馬上執行回調。         |------------------|         finalHandler(undefined)         |------------------|

錯誤方式2:

doSomething().then(doSomethingElse()).then(finalHandler);doSomething|-----------------|doSomethingElse(undefined)     //回調函數在注冊時就直接被調用|----------|         finalHandler(resultOfDoSomething)         |------------------|

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 福泉市| 达州市| 寿阳县| 新干县| 永寿县| 龙山县| 洪江市| 汉中市| 于都县| 舒兰市| 兴宁市| 榆树市| 沙田区| 通山县| 乌海市| 江都市| 于都县| 庆元县| 龙岩市| 荣昌县| 青海省| 博白县| 穆棱市| 镶黄旗| 大方县| 会理县| 牙克石市| 秦皇岛市| 波密县| 莫力| 吕梁市| 安远县| 阿鲁科尔沁旗| 三明市| 东海县| 应用必备| 洪洞县| 永善县| 福安市| 荔浦县| 衡水市|