摘要:一旦非同步操作完成,就調用指定的回調函數,并總是返回一個對象,方便鏈式調用。方法接受兩個回調函數作為參數,第一個參數是成功時的回調,第二個是失敗時的回調。方法,方法是定義在原型對象上的,作用是為對象添加回調函數。
先上一個大家比較熟悉的例子;
以前我們寫jquery ajax請求的時候,都是這樣寫:
$.ajax({ url: "test.json", success: function(){ alert("hello world!"); }, error:function(){ alert("error"); } });
后來呢在jquery1.7版本后,我們開始這樣寫:
$.ajax("test.json") .done(function(){ alert("hello world!"); }) .fail(function(){ alert("error"); });
很明顯,更改后的代碼更易懂易讀了。
這個是jquery的deferred對象,jquery deferred對象就是jQuery對Promises的實現,還其他有很多實現了promises的庫供開發者可用。 像微軟的 WinJS.Promise, when.js, q, 和dojo.Deferred,它們暴露的都是deferred對象。Promise也已經納入了ES6,對于jQuery實現Promises我們暫時就不講了,今天的目的是Promise。
其實呢,Promise就是一個對象,它是用來實現異步操作的,它可以讓異步代碼書寫起來更優雅,更便于閱讀。
Promise的特性:
1、Promise對象有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和 Rejected(已失敗),只有異步操作結果可以改變當前狀態,其他操作不能改變狀態,Promise對象的狀態只能從“進行中”改為“已完成”或者從“進行中”改為“失敗”。
2、Promise對象的then方法,就是用來指定回調函數。一旦非同步操作完成,就調用指定的回調函數,并總是返回一個promise對象,方便鏈式調用。而且同一個promise的then可以調用多次。
3、then方法接受兩個回調函數作為參數,第一個參數是成功Resolved時的回調,第二個是失敗Reject時的回調。第二個參數是可以選的,同時,then可以接受另一個promise傳入,也接受一個“類then”的對象或方法,即thenable對象。
我們現在用promise來組織一下代碼。
var sleep = function (time) { return new Promise(function (resolve, reject) { console.log("test123"); setTimeout(function () { resolve("test"); }, time); }) }; (function(){ console.log("start"); sleep(3000) .then(function(data){ console.log(data); return sleep(5000);}) .then(function(data){ console.log(data); console.log("end"); }) })();
上面代碼中,sleep方法返回一個Promise實例,表示一段時間以后才會發生的結果。首先輸出‘start’,然后,sleep執行后,3秒后返回“test”,觸發then方法綁定的回調函數,輸出回調返回值“test”,又return sleep(5000),這樣第一個then的返回值,就是第二個的參數,再次執行sleep,5秒后返回‘test’,輸出‘test’、"end";
好像沒有什么大不了的,promises的真正強大之處在于多重的鏈接,在異步執行的流程中,把執行代碼和處理結果的代碼清晰地分離了:它有個缺點就是鏈過長以后,滿屏幕的then,傻傻分不清業務到底干啥了,
Promise的 api1、Promise.resolve()
2、Promise.reject()
3、Promise.prototype.then()
4、Promise.prototype.catch()
5、Promise.all() // 所有的都有完成,相當于 且
6、Promise.race() // 完成一個即可,相當于 或
1、Promise.resolve()的作用將現有對象轉為Promise對象resolvedl;
Promise.resolve("test")==new Promise(resolve=>resolve("test"))
2、Promise.reject()也是返回一個Promise對象,狀態為rejected;
let p=Promise.reject("error") == let p=new Promise((resolve,reject)=>reject("error")); p.catch(data=>{ console.log(data); })
生成一個Promise對象的實例對象p,拋出錯誤,狀態就會變為Rejected,調用p.catch()指定的回調函數。
3、.then()方法,then方法是定義在原型對象Promise.prototype上的,作用是為Promise 對象添加回調函數。
let p=new Promise(resolve=>resolve("hello")); p.then((resolve,reject)=>{ console.log(resolve); }).then(function(){ console.log("zhangsan"); })
then方法的第一個參數是Resolved狀態的回調函數,第二個參數(可選)是Rejected狀態的回調函數。 可以使用鏈式操作,指定多個then(),依次執行,上面的代碼輸出結果:’hello‘,"zhangsan"
4、.catch():發生錯誤的回調函數,同樣,catch方法也是定義在原型對象Promise.prototype上的,事例同Promise.reject()的例子。注:如果Promise的狀態已經變為resolved,再拋出錯誤是無效的。
var p = new Promise(function(resolve, reject) { resolve("success"); reject("fail"); }); p.then(function(value) { console.log(value) }) .catch(function(error) { console.log(error) });
輸出結果:success;
5、Promise.all()的作用是同時執行多個實例,同步并行,且所以的實例都返回resolve狀態,Promise才會改變為resolve狀態,其中一個為rejected,promise的狀態就是rejected;
注:Promise.all 方法的參數可以不是數組,但是必須是一個Iterator接口對象,且返回promise實例,否則報錯:error:TypeError: [object Promise] is not iterable!
let p1 =new Promise(function(resolve,reject){ resolve(1); }); let p2 = new Promise(function(resolve,reject){ resolve(2); }); let p3 = new Promise(function(resolve,reject){ // reject(); resolve(3); }); Promise.all([p1, p2, p3]).then(function (results) { console.log("success:"+results); }).catch(function(r){ console.log("error"); console.log(r); });
上面代碼輸出:success:1,2,3;
把 p3方法改為返回 reject();輸出結果是:error;
6、Promise.race()的作用也是同時執行多個實例,只要有一個實例改變狀態,Promise就改為那個實例所改變的狀態;
let p1 =new Promise(function(resolve,reject){ setTimeout(function(){ reject(1); },3000) }); let p2 = new Promise(function(resolve,reject){ setTimeout(function(){ resolve(2); },1000) }); Promise.race([p1, p2]).then(function (results) { console.log("success:"+results); }).catch(function(results){ console.log("error:"+results); }); 輸出:success: 2;
上面代碼p2首先執行完畢,改變狀態為resolve,所以promise的狀態被改為resolve;
我們把p1的時間改為1000,p2改為3000,也就是說p1先執行完畢,promise的狀態也被改變為reject,輸出:error:1
如果想深入學習,可以看一下阮一峰的《ES 6標準入門》的Promise部分http://es6.ruanyifeng.com/#do...,很詳細的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81790.html
摘要:三是控制反轉控制權在其他人的代碼上,假如異步函數是別人提供的庫,我們把回調函數傳進去,我們并不能知道異步函數在調用回調函數之外做了什么事情。錯誤捕捉相比回調函數的錯誤無法在外部捕捉的問題,能夠為一連串的異步調用提供錯誤處理。 前言 《JS異步編程之 callback》一文我們了解了JS 是基于單線程事件循環的概念構建的,回調函數不會立即執行,由事件輪詢去檢測事件是否執行完畢,當執行完有...
摘要:到這里,我已經發出了一個請求買漢堡,啟動了一次交易。但是做漢堡需要時間,我不能馬上得到這個漢堡,收銀員給我一個收據來代替漢堡。到這里,收據就是一個承諾保證我最后能得到漢堡。 同期異步系列文章推薦談一談javascript異步javascript異步中的回調javascript異步之Promise.all()、Promise.race()、Promise.finally()javascr...
摘要:所以,函數的一個重要實際意義就是用來處理異步操作,改寫回調函數。表示在這里等待異步操作返回結果,再繼續執行。 JS異步之Promise,Generator,Async Promise 解決的問題:回調地獄 Promise規范: promise有三種狀態,等待(pending)、已完成(fulfilled/resolved)、已拒絕(rejected).Promise的狀態只能從...
摘要:所以,函數的一個重要實際意義就是用來處理異步操作,改寫回調函數。表示在這里等待異步操作返回結果,再繼續執行。 JS異步之Promise,Generator,Async Promise 解決的問題:回調地獄 Promise規范: promise有三種狀態,等待(pending)、已完成(fulfilled/resolved)、已拒絕(rejected).Promise的狀態只能從...
摘要:所以,函數的一個重要實際意義就是用來處理異步操作,改寫回調函數。表示在這里等待異步操作返回結果,再繼續執行。 JS異步之Promise,Generator,Async Promise 解決的問題:回調地獄 Promise規范: promise有三種狀態,等待(pending)、已完成(fulfilled/resolved)、已拒絕(rejected).Promise的狀態只能從...
閱讀 2472·2021-11-24 09:39
閱讀 3518·2019-08-30 15:53
閱讀 594·2019-08-29 15:15
閱讀 2903·2019-08-26 13:23
閱讀 3212·2019-08-26 10:48
閱讀 643·2019-08-26 10:31
閱讀 748·2019-08-26 10:30
閱讀 2359·2019-08-23 18:32