未來值
設想場景:你去漢堡店買漢堡,購買人數很多,無法立刻拿到漢堡,
當你付款完成后,就發出了對某個值(這里就是漢堡)的請求,此時店員就會給你一個東西代替漢堡,通常是帶有編號的收據,那么收據上的編號就是你核銷漢堡的憑證,這個編號也代表了漢堡店給你的承諾(promise),即,未來會給你一個漢堡,
此時有了收據,就可以等待(等待態)了,在等待的途中,你可以做其他的事情,
但是漢堡依舊在你的大腦中,你不會等到漢堡送來時產生“為什么給我個漢堡?”等其它疑惑,所以當漢堡送來時,你就會直接處理這個值(漢堡)——把它吃掉,
此時這個在大腦中的漢堡,你也可以理解為即將得到的漢堡,是一個“未來值”,即占住了位置,但并沒有拿到實物進行處理,反而你正在做其他事,
等待片刻后,叫到了你的號碼,你可以去領漢堡了,
此時會發生3種情況,
-
核對編號成功,完成交易,拿到漢堡,即,我需要的值(漢堡),已經處理好了,我拿承諾值(商家給的編號)換取這個值本身(漢堡),此時,未來值成功了(得到漢堡了),結果就是你就開始吃漢堡了,吃飽了,
-
核對編號成功,漢堡賣完了,值(漢堡)沒了,未來值(即將得到漢堡)失敗了(漢堡并沒得到),結果是你可能會換一個地方吃或者干別的,
-
商家系統故障,你的號永遠都沒被叫到,現實中有現實中的處理辦法,但在程式中,這是一種未決議狀態,
從上面的例子可以看出,核對編號到拿到/未拿到漢堡到最終是吃還是沒吃的結果,這是一個完整的程序,重要的是最后的結果,是吃了還是沒吃,
這基本詮釋了使用Promise的整個流程,即Promise先決議,然后確定未來值的狀態,有成功也有失敗,成功后對應一種結果回傳,失敗后對應一種結果回傳,且只會有一種結果被回傳,
未決議狀態會放在之后討論,
Promise
Promise:從語意上可以看出,它是一個承諾,承諾一段時間后給你反饋一個結果,從語法上,它是一個物件,使用new來創建,它會有三種狀態,等待pending、成功resolve、失敗rejecte,且一旦狀態確定,就無法更改,此時它成了不變值,
Promise創建的任務是微任務,
未決議狀態會放在之后討論,它不是主觀觸發的一種狀態,而以上三種,是promise必備的狀態,
此時你是否想到未來值,它也有成功/失敗的狀態,
所以說:Promise會很好的展現未來值的特性,是一種封裝和組合未來值的易于復用的機制,
來看看Promise的使用語法,
let p1 = new Promise((resolve, reject) => {
// resolve("成功");
reject("拒絕");
})
使用決議函式reject()表示失敗(請求拒絕),
使用決議函式resolve()表示成功,
注意,這里為了一次展示語法也為了代碼能正常執行,我將resolve(“成功”)注釋掉了,因為狀態一旦確定就無法更改,如果沒有注釋,那意思就是,先成功,后又改為失敗,這樣是不行的,只能有一個狀態存在,所以將其中一個注釋掉,
使用new來創建的promsie是標準promise,
Promise內封裝了“等待底層值的完成或拒絕”的狀態,這個狀態依賴于時間,所以是這個狀態與時間有關,而promise本身與時間無關,可以得出:Promise可以按照可預測的方式進行組合,不用擔心時序帶來的變化或底層的結果,這可以避免很多傳統異步的問題,之后我們會詳細討論,
同樣的,Promise的狀態不可更改會帶來一些好處:
使用Promise決議過的值是不變值,外部無法進行更改,那么,將這個值傳給第三方,或者多方進行觀察,它就更加安全了,因為無法被修改,
由于狀態不可更改,導致Promise產生的任務有以下特點:單一、不可逆、不可撤銷,所以,一個Promise,不能有兩種狀態賦予,
單獨的Promise展現了未來值的特性,但是,就像核銷編號完成后拿到/未拿到漢堡所產生的結果例如:吃漢堡或換家店一樣,Promise完成之后,會有一個東西來執行后面的事情,然后回傳一些東西,
使用then()方法來執行得到成功/失敗狀態后的事情,
Then()
then()方法就像是promise的配套組件,每一個promise都會有一個對應的then()
then()方法內有兩個引數,即兩個方法,分別接收resolve()和reject()傳遞過來的“信號”,收到成功狀態的信號,就傳給then()的第一個函式value,收到失敗狀態的信號,就傳給第二個引數reason,這里使用箭頭函式,你可以使用其它函式方法和命名,
new Promise((resolve, reject) => {
resolve("操作成功,這是業務1");
// reject("拒絕狀態,這是拒絕的業務處理 ");
})
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> {
console.log("成功業務處理 1");
},
reason => {
console.log("拒絕的業務處理");
}
)
這里注釋掉了reject(),保留了resolve狀態,所以傳遞到then()時就會執行value,輸出“成功業務處理1”,
注意:promise物件有幾個引數,就要給then()幾個引數,即使是null,
一般是兩個引數,
new Promise((resolve, reject) => {
resolve("操作成功,這是業務1");
// reject("拒絕狀態,這是拒絕的業務處理 ");
})
.then(
msg => {
console.log("success:" + msg);
},null)
這里對于reject狀態并不想處理,所以沒有處理方法,使用null,但不能沒有,會報錯,
沒有null:

Promise不僅可以用于異步問題,還能用于很多地方,這些稍后會說,現在先考慮promise最基本的方法,
鏈式Promise
在正式開始說鏈式Promise之前,我們需要搞清楚三個概念,
-
每個then()都是一個Promise物件,
-
是否在promise中return,
-
每個then()會優先處理離自己最近的那個promise,
先來看看第一點,
let p1 = new Promise((resolve, reject) => {
reject("rejected");
});
let p2 = p1
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
reason => console.log(reason)
)
console.log(p2)
其中p2就是p1的then(),將它列印出來,

可以看到,它是一個準備態的promise,
對它的操作,要么就把它當作一個準備好的微任務并放入任務串列中,要么就將它看作一個promise,為它再配套一個then(),來對這個then()產生的結果再次進行處理,
let p1 = new Promise((resolve, reject) => {
reject("rejected");
});
let p2 = p1
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
reason => console.log(reason)
)
.then(//.then對上一個promise進行處理,即p1.then
a => console.log("成功"),
b => console.log(b)
);
第二個then()就在處理第一個then()了,可以看下運行結果,
let p1 = new Promise((resolve, reject) => {
//resolve("fulfilled");
reject("rejected");
});
let p2 = p1
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
reason => console.log(reason)
)
.then(//.then對上一個promise進行處理,即p1.then
a => console.log("成功"),
b => console.log("失敗")
);
注意:兩個then()之間不能插入任何的東西,
你覺得輸出的結果會是什么?
先看下瀏覽器的結果,與你的理解可能會有偏差,

你會不會覺得第二個輸出,應該是“失敗”?為什么會是成功?不是reject從上到下傳過來的嗎?
注意:第二個then()是對上一個then()進行了處理,我們對現在的p2,也就是第一個then()進行輸出,看下它的狀態,
注意:由于宏任務,微任務,同步任務的關系,我們設定一個定時器來讓輸出陳述句在微任務之后進行,才能看到微任務執行后的結果,
let p1 = new Promise((resolve, reject) => {
//resolve("fulfilled");
reject("rejected");
});
let p2 = p1
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> console.log(value),
reason => console.log(reason)
)
.then(//.then對上一個promise進行處理,即p1.then
a => console.log("成功"),
b => console.log(b)
);
setTimeout(() => {
console.log(p2);
});

可以看到p2的狀態是“fulfilled”,也就是成功了,所以在第二個then()中,執行了a,輸出“成功”,
原因:第二個then()處理的是第一個then(),第一個then()接收到起始promise的信號,并處理了它,它的處理程序是很成功的,所以它是成功的,它的狀態與起始promise無關,所以在接下來的第二個then()處理它時,是按照成功的狀態走的,所以執行成功,
那有沒有什么辦法,讓我們自定義傳給第二個then()的promise的狀態,
當然可以,但是并不是簡單的使用then()一直往下串,我們還是需要創建新的promise物件來重新賦予任務狀態,
此時就要討論第二點了,先看上個問題的解決辦法,
只需要在第一個then()當中新創建一個promise并且return它即可,
let p1 = new Promise((resolve, reject) => {
resolve("fulfilled");
})
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> {
return new Promise((resolve, reject) => {//只要return了,后面的then針對的就是這個return的新promise
reject("處理失敗");
})
},
reason => console.log(reason)
)
.then(//此時的then是對上面的then的處理
value =https://blog.csdn.net/weixin_42309926/article/details/> {
console.log("成功:" + value);
},
reason => console.log("error" + reason)
);
在瀏覽器中查看結果,

起初的promise狀態為resolve,所以執行value中的函式,value將新的promise回傳,而這個新的promise的狀態是reject,所以走到第二個then()中的reason(),列印出“erro處理失敗”,
這個程序很像工廠的流水線,比如做面包,原料經過第一個機器,被做成面包胚,再經過第二個機器,被烤熟,最后的結果就是得到一個熟的面包,之前的原料和生面包胚都不復存在,沒有人會在意它們,只會在意到手的面包,
但是,注意:第一個機器需要將面包胚吐出來,才能到下一個機器那里進行加工,這就是為什么要return這個promise的原因,我們需要將當前的promise進行回傳,才能讓下一個then()處理它,
有回傳就有不回傳,不回傳會怎么樣呢?
就像原料卡在機器里不出來一樣,整個成產線都崩潰了,看看瀏覽器里的情況,

成功了是因為我們新建的promise并不影響整體流程,像之前說過的一樣,經過一輪一輪then()的處理就行,那undefined呢?
Undefined和下一行錯誤息息相關,因為我們新建了promise卻沒有給它相對應的then(),所以這個promise是不能正常創建任務的,它什么都沒有給下一個then(),但是它的狀態是resolve(),所以是“成功:undefined”,
所以說,當你需要一步一步處理你的promise時,千萬不要忘了return,
可是,并不總是需要處理標準的promise物件,就像一樣的原料,我可以讓它變成面包胚、披薩餅、或者其它的東西再傳送出去一樣,我們也可以回傳其它的型別,
例如普通的物件和類,
先來看回傳普通的物件,
let p1 = new Promise((resolve, reject) => {
resolve("fulfilled");
})
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> {
return{//回傳普通的物件
name:"Cherrie"
}
},
reason => {}
)
.then(
value =https://blog.csdn.net/weixin_42309926/article/details/> {
console.log(value);
console.dir(value);
},
reason => {
console.log(reason);
}
);
在瀏覽器里列印它,

物件就被回傳出來了,你也可以使用它回傳其他需要的型別,回傳類,修改以上代碼即可,這里不多贅述,
在這里強調它可以回傳其它型別值的原因是,我們可以通過這個特點來回傳除標準promise以外的其它類promise型別,也就是類似標準promise的promise型別,不是我們使用的class哦,
剩下的內容會盡快更新,每日更新或每兩日更新,敬請期待~~
omise((resolve, reject) => {
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/1411.html
標籤:python
上一篇:JWT的基本介紹
