Promise是異步編程的一種解決方案,可以幫助我們解決回調(diào)地獄的問題,網(wǎng)絡(luò)上有很多這方面的教程,但都很晦澀難懂,本文盡可能讓大家更容易的理解promise
文章開始前先問大家一個問題,燒一壺水需要10分鐘,煮飯需要30分鐘,掃地需要5分鐘、那么媽媽讓小明燒水煮飯而且把地掃干凈需要用多少分鐘呢?
壓根不用想就知道是30分鐘、燒水的同時也可以煮飯也可以掃地、我們只需要等水燒開時把火關(guān)掉就可以了
ES6規(guī)定,Promise對象是一個構(gòu)造函數(shù),用來生成Promise實(shí)例。
基本使用
1.我們直接上代碼,看看運(yùn)行結(jié)果
var Obj=new Promise(function(){
console.log("hello 凱旋");
});
//hello 凱旋
Promise構(gòu)造函數(shù)接受一個函數(shù)當(dāng)做參數(shù),而且創(chuàng)建后會立即執(zhí)行這個函數(shù)
2.有了對上面那些粗淺的認(rèn)識,我們現(xiàn)在就可以完成一個回調(diào)的案例(這只是我的一個惡趣味(逃····)
有三個方法t1、t2、t3 ,要求 t1執(zhí)行完后執(zhí)行t2,t2執(zhí)行完后執(zhí)行t3
//正常來說是這樣去做 t1(t2(t3))
function t1(){
console.log("老子是t1");
return new Promise(t2);
}
function t2(){
console.log("老子是t2");
return new Promise(t3);
}
function t3(){
console.log("老子是t3");
}
new Promise(t1);//依次執(zhí)行 t1、t2、t3
這個案例就是借助了 Promise創(chuàng)建后會立即執(zhí)行這個特點(diǎn) 接下來我們開始正經(jīng)的說說Promise
3.上面說了Promise構(gòu)造函數(shù)接受一個函數(shù)當(dāng)參數(shù) 也就是這樣
var Obj=new Promise(function(){});
但其實(shí)這個函數(shù)也接收兩個參數(shù)
var promise = new Promise(function(resolve, reject) {})
這兩個參數(shù)分別是resolve和reject。它們是兩個函數(shù),這倆函數(shù)是JavaScript引擎提供的,不用咱們自己管。
那么他們是干啥的,我們看案例
var promise = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve("我是數(shù)據(jù)");
},3000);
})
promise.then(function(data){
console.log(data);
});
運(yùn)行后發(fā)現(xiàn) 三秒后會打印 我是數(shù)據(jù) 那么這是咋回事呢
Promise對象代表一個異步操作,有三種狀態(tài):Pending(進(jìn)行中)、Resolved(已完成,又稱Fulfilled)和Rejected(已失?。?。
resolve函數(shù)的作用是,將Promise對象的狀態(tài)從“未完成”變?yōu)椤俺晒Α保磸腜ending變?yōu)镽esolved),在異步操作成功時調(diào)用,并將異步操作的結(jié)果,作為參數(shù)傳遞出去;
reject函數(shù)的作用是,將Promise對象的狀態(tài)從“未完成”變?yōu)椤笆 保磸腜ending變?yōu)镽ejected),在異步操作失敗時調(diào)用,并將異步操作報出的錯誤,作為參數(shù)傳遞出去。
上面的字好長啊,實(shí)際濃縮一下就是這樣 我們調(diào)用 resolve這個方法的時候 就說明我們這個操作完成了 它會觸發(fā)promise.then這個方法 這個方法實(shí)際上也有倆參數(shù)(可以只寫一個),也是倆函數(shù),第一個是 當(dāng)執(zhí)行resolve后 調(diào)用的,第二個是執(zhí)行reject時候調(diào)用的, 這倆函數(shù)的參數(shù)就是調(diào)用resolve和reject時傳過來的值
4.來看個案例吧 這么多字寫的我也頭疼
var promise = new Promise(function(resolve, reject) {
setTimeout(function(){
reject("我是錯誤");
},3000);
})
promise.then(function(data){
console.log(data);
},function(error){
console.log(error)
});
上面代碼就會打印出 我是錯誤
5.then方法指定的回調(diào)函數(shù),將在當(dāng)前腳本所有同步任務(wù)執(zhí)行完才會執(zhí)行
var promise = new Promise(function(resolve, reject) {
console.log('Promise'); resolve();
});
promise.then(function() {
console.log('Resolved.');
});
console.log('Hi!');
// Promise
// Hi!
// Resolved
6.then的鏈?zhǔn)讲僮?案例
function t1() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("t1");
}, 1000);
});
return promise;
}
function t2() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("t2");
}, 1000);
});
return promise;
}
function t3() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("t3");
}, 1000);
});
return promise;
}
t1().then(function(data) {
console.log(data);
return t2();
}).then(function(data) {
console.log(data);
return t3();
}).then(function(data) {
console.log(data);
});
每一次調(diào)用then必須返回一個新的promise來實(shí)現(xiàn)這個鏈?zhǔn)秸{(diào)用
catch
其實(shí)它和then的第二個參數(shù)一樣,用來指定reject的回調(diào)
function t1() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject("出錯了");
}, 1000);
});
return promise;
}
t1().then(function(data) {
console.log(data);
return t2();
}).catch(function(error){
console.log(error)
}
);
我們沒有指定reject回調(diào)的時候 就執(zhí)行它 它還有個功能就是 假設(shè)我們執(zhí)行了resolve的回調(diào) 里面出錯了 它不會中斷執(zhí)行 而是進(jìn)入catch
all與race
1.arr的基本使用
function t1() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("t1");
}, 1000);
});
return promise;
}
function t2() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("t2");
}, 2000);
});
return promise;
}
function t3() {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("t3");
}, 3000);
});
return promise;
}
Promise.all([t1(), t2(), t3()]).then(function(results) {
console.log(results);
});
//["t1", "t2", "t3"]
其實(shí)就是等所有的異步操作做完,才執(zhí)行when 而且返回的是個數(shù)組(所有異步操作的)
race與all不同之處就是在于 誰先完成這個異步操作,誰就執(zhí)行when操作 返回的是最先完成異步操作的