Promise
解決的問(wèn)題:回調(diào)地獄
Promise 規(guī)范:
promise 有三種狀態(tài)泡嘴,等待(pending)、已完成(fulfilled/resolved)、已拒絕(rejected)
.Promise 的狀態(tài)只能從“等待”轉(zhuǎn)到“完成”或者“拒絕”,不能逆向轉(zhuǎn)換仗考,同時(shí)“完成”和 “拒絕”也不能相互轉(zhuǎn)換.
promise 必須提供一個(gè) then 方法以訪問(wèn)其當(dāng)前值、終值和據(jù)因词爬。promise.then(resolve, reject),resolve 和 reject 都是可選參數(shù)秃嗜。如果 resolve 或 reject 不是函數(shù),其必須被忽略.
then 方法必須返回一個(gè) promise 對(duì)象.
使用:
實(shí)例化 promise 對(duì)象需要傳入函數(shù)(包含兩個(gè)參數(shù)),resolve 和 reject,內(nèi)部確定狀態(tài).resolve 和 reject 函數(shù)可以傳入?yún)?shù)在回調(diào)函數(shù)中使用.
resolve 和 reject 都是函數(shù),傳入的參數(shù)在 then 的回調(diào)函數(shù)中接收.
var promise = new Promise(function(resolve, reject) {
setTimeout(function(){
resolve('好哈哈哈哈');
});
});
promise.then(function(val){
console.log(val)
})
then 接收兩個(gè)函數(shù),分別對(duì)應(yīng) resolve 和 reject 狀態(tài)的回調(diào),函數(shù)中接收實(shí)例化時(shí)傳入的參數(shù).
promise.then(val=>{
//resolved
},reason=>{
//rejected
})
catch 相當(dāng)于.then(null, rejection)
當(dāng) then 中沒(méi)有傳入 rejection 時(shí),錯(cuò)誤會(huì)冒泡進(jìn)入 catch 函數(shù)中,若傳入了 rejection,則錯(cuò)誤會(huì)被 rejection 捕獲,而且不會(huì)進(jìn)入 catch.此外,then 中的回調(diào)函數(shù)中發(fā)生的錯(cuò)誤只會(huì)在下一級(jí)的 then 中被捕獲,不會(huì)影響該 promise 的狀態(tài).
new Promise((resolve,reject)=>{
throw new Error('錯(cuò)誤')
}).then(null,(err)=>{
console.log(err,1);//此處捕獲
}).catch((err)=>{
console.log(err,2);
});
// 對(duì)比
new Promise((resolve,reject)=>{
throw new Error('錯(cuò)誤')
}).then(null,null).catch((err)=>{
console.log(err,2);//此處捕獲
});
// 錯(cuò)誤示例
new Promise((resolve,reject)=>{
resolve('正常');
}).then((val)=>{
throw new Error('回調(diào)函數(shù)中錯(cuò)誤')
},(err)=>{
console.log(err,1);
}).then(null,(err)=>{
console.log(err,2);//此處捕獲,也可用 catch
});
兩者不等價(jià)的情況:
此時(shí)顿膨,catch 捕獲的并不是 p1 的錯(cuò)誤锅锨,而是 p2 的錯(cuò)誤,
p1().then(res=>{
return p2()//p2 返回一個(gè) promise 對(duì)象
}).catch(err=> console.log(err))
一個(gè)錯(cuò)誤捕獲的錯(cuò)誤用例:
該函數(shù)調(diào)用中即使發(fā)生了錯(cuò)誤依然會(huì)進(jìn)入then 中的resolve 的回調(diào)函數(shù),因?yàn)楹瘮?shù) p1中實(shí)例化 promise 對(duì)象時(shí)已經(jīng)調(diào)用了 catch,若發(fā)生錯(cuò)誤會(huì)進(jìn)入 catch 中,此時(shí)會(huì)返回一個(gè)新的 promise,因此即使發(fā)生錯(cuò)誤依然會(huì)進(jìn)入 p1 函數(shù)的 then 鏈中的 resolve 回調(diào)函數(shù).
function p1(val){
return new Promise((resolve,reject)=>{
if(val){
var len = val.length;//傳入 null 會(huì)發(fā)生錯(cuò)誤,進(jìn)入 catch 捕獲錯(cuò)
resolve(len);
}else{
reject();
}
}).catch((err)=>{
console.log(err)
})
};
p1(null).then((len)=>{
console.log(len,'resolved');
},()=>{
console.log('rejected');
}).catch((err)=>{
console.log(err,'catch');
})
Promise 回調(diào)鏈:
promise 能夠在回調(diào)函數(shù)里面使用 return 和 throw虽惭, 所以在 then 中可以 return 出一個(gè) promise 對(duì)象或其他值橡类,也可以 throw 出一個(gè)錯(cuò)誤對(duì)象,但如果沒(méi)有 return芽唇,將默認(rèn)返回 undefined,那么后面的 then 中的回調(diào)參數(shù)接收到的將是 undefined.
function p1(val){
return new Promise((resolve,reject)=>{
val==1?resolve(1):reject()
})
};
function p2(val){
return new Promise((resolve,reject)=>{
val==2?resolve(2):reject();
})
};
let promimse = new Promise(function(resolve,reject){
resolve(1)
})
.then(function(data1) {
return p1(data1)//如果去掉 return,則返回 undefined 而不是 p1 的返回值,會(huì)導(dǎo)致報(bào)錯(cuò)
})
.then(function(data2){
return p2(data2+1)
})
.then(res=>console.log(res))
Generator 函數(shù):
generator 函數(shù)使用:
1取劫、分段執(zhí)行匆笤,可以暫停
2、可以控制階段和每個(gè)階段的返回值
3谱邪、可以知道是否執(zhí)行到結(jié)尾
function* g() {
var o = 1;
yield o++;
yield o++;
}
var gen = g();
console.log(gen.next()); // Object {value: 1, done: false}
var xxx = g();
console.log(gen.next()); // Object {value: 2, done: false}
console.log(xxx.next()); // Object {value: 1, done: false}
console.log(gen.next()); // Object {value: undefined, done: true}
generator 和異步控制:
利用 Generator 函數(shù)的暫停執(zhí)行的效果炮捧,可以把異步操作寫(xiě)在 yield 語(yǔ)句里面,等到調(diào)用 next 方法時(shí)再往后執(zhí)行惦银。這實(shí)際上等同于不需要寫(xiě)回調(diào)函數(shù)了咆课,因?yàn)楫惒讲僮鞯暮罄m(xù)操作可以放在 yield 語(yǔ)句下面末誓,反正要等到調(diào)用 next 方法時(shí)再執(zhí)行。所以书蚪,Generator 函數(shù)的一個(gè)重要實(shí)際意義就是用來(lái)處理異步操作喇澡,改寫(xiě)回調(diào)函數(shù)。
async 和異步:
用法:
async 表示這是一個(gè) async 函數(shù)殊校,await 只能用在這個(gè)函數(shù)里面晴玖。
await 表示在這里等待異步操作返回結(jié)果,再繼續(xù)執(zhí)行为流。
await 后一般是一個(gè) promise 對(duì)象
示例:async 用于定義一個(gè)異步函數(shù)呕屎,該函數(shù)返回一個(gè) Promise。
如果 async 函數(shù)返回的是一個(gè)同步的值敬察,這個(gè)值將被包裝成一個(gè)理解 resolve 的 Promise秀睛, 等同于 return Promise.resolve(value)。
await 用于一個(gè)異步操作之前莲祸,表示要“等待”這個(gè)異步操作的返回值蹂安。await 也可以用于一個(gè)同步的值。
let timer = async function timer(){
return new Promise((resolve,reject) => {
setTimeout(() => {
resolve('500');
},500);
});
}
timer().then(result => {
console.log(result); //500
}).catch(err => {
console.log(err.message);
});
//返回一個(gè)同步的值
let sayHi = async function sayHi(){
let hi = await 'hello world';
return hi; //等同于 return Promise.resolve(hi);
}
sayHi().then(result => {
console.log(result);
});