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