一.為什么會出現(xiàn)promise
todo:回調(diào)地獄函數(shù)實例
比如我們要查找浙江省杭州市黎明縣東鄉(xiāng)鎮(zhèn)的豐田X系的車的價格嚎朽,我們可能得這么寫:
getSheng(){ // 獲取全國有哪些省
if(res1.success){
getShi('浙江省'){ // 獲取浙江省下面的市
if(res2.success){
getQu('杭州市'){ // 獲取杭州市下面的縣
if(res3.success){
getZhen('黎明縣'){ // 獲取黎明縣下面的鎮(zhèn)
if(res4.success){
getBrand('東鄉(xiāng)鎮(zhèn)'){ // 獲取東鄉(xiāng)鎮(zhèn)里面有什么車
if(res5.success){
getChexi('豐田'){ // 獲取東豐田下的車系
if(res6.success){
getPrice('X系列'){ // 獲取X系列的價格
if(res7.success){
console.log(res6.data.price)
}
}
}
}
}
}
}
}
}
}
}
}
}
}
這樣的代碼看起來很煩吧,這還算是友好的嵌施,
這個是異步回調(diào)奈泪,還有跟多異步和同步代碼混合在一起,寫的時候一時爽佛析,維護代碼火葬場栗精,等需要改代碼的時候光理清他們的執(zhí)行順序可能就得耗費一片腦細胞闯参。但是在我們的代碼中經(jīng)常會寫出兩三層異步嵌套,各種同步異步混合的代碼悲立,就想問事情能變得簡單一點嗎鹿寨?
二. promise用法
當前可以,我們先用promise實現(xiàn)上面的功能
實現(xiàn)一下上面的函數(shù)
每一個promise都會提供一個then()函數(shù)薪夕,在這個then里面的函數(shù)脚草,我們可以做這些事情:
1.return另一個promise
2.return一個同步的值(或者undefined)
3.throw一個同步異常
promise寫法
Promise是一個構(gòu)造函數(shù),它接受一個函數(shù)作為參數(shù)原献,這個函數(shù)又有兩個參數(shù)分別為resolve和reject馏慨,這兩個參數(shù)也是函數(shù)。
resolve姑隅、reject
Promise是一種代碼結(jié)構(gòu)和流程写隶,類似于一個狀態(tài)機,有三種狀態(tài)讲仰,等待(pending)慕趴,成功(fulfilled),失敗(reject)--todo:吧resolve鄙陡,reject對應的函數(shù)用箭頭在圖上標出來冕房,方便理解--。成功趁矾,則執(zhí)行resolve耙册,失敗則執(zhí)行reject。一般情況下毫捣,你可以指定什么情況執(zhí)行resolve详拙,什么情況執(zhí)行reject。但如果程序執(zhí)行出現(xiàn)錯誤培漏,會直接執(zhí)行reject,如果找不到reject或者reject對應的函數(shù)胡本,程序會直接報錯牌柄。我們來幾個例子:
例子一:打印結(jié)果是啥?
function fn1() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn1')
},1000)
})
}
function fn2() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn2')
},2000)
})
}
fn1().then(fn2)
.then()是Promise實例的方法侧甫,它定義在原型對象(Promise.prototype)上. 接受兩個參數(shù)珊佣,這兩個參數(shù)都是函數(shù)蹋宦,第一個函數(shù)處理resolve(res),第二個函數(shù)處理reject(error);
例子二:打印結(jié)果是什么?
function fn1() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn1')
reject('錯誤'+'fn1')
},1000)
})
}
fn1().then(fn2)
const promise = new Promise(function(resolve, reject) {
// 異步操作的代碼
if(success) {
return resolve(data); // data為異步操作成功返回的數(shù)據(jù)
} else {
return reject(error); //data為失敗時返回的數(shù)據(jù)
}
})
2.ES6提供了一個原生的構(gòu)造函數(shù)Promise咒锻,promise用法
3.promise原理
promise本質(zhì)上是一個綁定了回調(diào)的對象冷冗,而不是將回調(diào)傳進函數(shù)內(nèi)部。惑艇?蒿辙??
promise的鏈式調(diào)用:
then函數(shù)會返回一個新的promise滨巴,跟原來的不同:
const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);
為什么說promise是語法糖:
我們希望將例子一的寫法轉(zhuǎn)換成例子二的寫法:
- 例子一
doSomething(function(value){
console.log('Got a value'+value)
})
- 例子二
doSomething().then(function(value){
console.log('Got a value'+value)
})
如何實現(xiàn)上面的轉(zhuǎn)換呢思灌?
function doSomething(){
return {
then:function(callback){
var value = 32;
callback(value)
}
}
}
4.與Async等的對比
參考文檔:
https://juejin.im/entry/57513df25bbb5000642e95ba
https://juejin.im/post/5a730110f265da4e777f7792