(1) var
- var在函數(shù)外定義,是全局變量饰潜,函數(shù)內(nèi)可以使用
- var在函數(shù)內(nèi)定義初坠,是局部變量,函數(shù)外不能使用
- var 在其他代碼塊中定義彭雾,是全局變量 ----- 如 if 等
var x = 10;
(
function fun() {
var y = 20;
console.log(x) // 10
}
)();
console.log(y) // 報錯 y is not defined ----- var在函數(shù)內(nèi)部定義某筐,是局部變量,函數(shù)外無法讀取
-------------------------------------
if (true) {
var z = 300;
}
console.log(z) // 300 // var在其他代碼塊中定義冠跷,是全局變量
(2) 對象es6
- 表達式 - 可以作為對象的屬性名和方法名
- 變量名可以直接作為對象屬性名
- 對象中的方法可以簡寫
let ani = 'animal'
let nam = 'name'
let newAr = {
ani // 變量名直接作為對象的屬性名,等同于 ( ani: ani 即 ani: animal) 前者是字符串身诺,后者ani是變量
nam,
[ani + nam] : 2000, // 中括號中寫表達式蜜托,作為對象的屬性名或方法名
getAge() { // 方法名簡寫,相當于 getAge: funciton() { console.log(this.animalname) }
console.log(this.animalname)
}
}
newAr.getAge();
console.log(newAr,'newAr')
Promise
Promise含義
- promise是一種異步編程的解決方案
- 比傳統(tǒng)的 回調(diào)函數(shù)和事件 更強大
Promise具體是什么霉赡?
- promise是一個容器橄务,里面保存著某個未來才會結(jié)束的事件 (比如 異步操作的結(jié)果)
- 語法上:promise是一個對象,可以從它獲取異步操作的消息
- promise提供統(tǒng)一的api穴亏,所以各種異步操作都可以用同樣的方法進行處理
Promise對象的特點蜂挪?
- promise對象的狀態(tài)不受外界影響 ----- ( promise有三種狀態(tài) )
pending進行中,fulfilled已成功嗓化,rejected已失敗
只有異步操作的結(jié)果可以決定當前是哪一種狀態(tài)棠涮,其他別的操作無法改變這個狀態(tài) - promise的狀態(tài)一旦改變,就不會再變刺覆,任何時候都能得到這個結(jié)果
promise狀態(tài)改變只有兩種情況:pending狀態(tài) 變?yōu)?fulfilled狀態(tài)
和pending狀態(tài) 變?yōu)?rejected狀態(tài)
只要這兩種情況發(fā)生严肪,狀態(tài)就凝固了,不會再改變谦屑,稱為 ( resolved ) 已定型
例如:只要改變已經(jīng)發(fā)生了驳糯,你再對promise對象添加回調(diào)函數(shù),也會立即得到這個結(jié)果
Promise vs 事件氢橙?
Promise:只要改變已經(jīng)發(fā)生了酝枢,你再對promise對象添加回調(diào)函數(shù),也會立即得到這個結(jié)果
event----: 如果改變發(fā)生了悍手,你再去監(jiān)聽帘睦,得不到結(jié)果
Promise對象 的優(yōu)缺點袍患?
- 優(yōu)點
promise對象,可以將 異步操作 以 同步操作的流程 表達出來官脓,避免層層嵌套 - 缺點
(1) promise一旦新建协怒,就會立即執(zhí)行,無法取消
(2) 如果不設(shè)置回掉函數(shù)卑笨,promise內(nèi)部拋出的錯誤就不會反應(yīng)到外部
(3) 處于pending狀態(tài)時孕暇,是不能知道目前進展到哪個階段的 ( 剛開始?赤兴,即將結(jié)束妖滔?)
Promise構(gòu)造函數(shù)
es6規(guī)定,Promise對象 是一個構(gòu)造函數(shù)桶良,用來生成Promise實例
- Promise構(gòu)造函數(shù)座舍,接受一個函數(shù)作為參數(shù),該函數(shù)有兩個參數(shù)分別是 resolve 和
reject陨帆,它們是兩個函數(shù) - resolve 和 reject 由 javascript 引擎提供曲秉,不用自己部署
- resolve函數(shù)
resolve函數(shù)的作用是,將Promise對象的狀態(tài)疲牵,由pending=>變?yōu)閒ulfilled承二,在異步操作成功時調(diào)用笛臣,并將異步操作的結(jié)果砌滞,作為參數(shù)傳遞出去 - reject函數(shù)
reject函數(shù)的作用是春霍,將Promise對象的狀態(tài)辞色,由pending=>變?yōu)閞ejected刑赶,在異步操作失敗時調(diào)用箕憾,并將異步操作報出的錯誤袍辞,作為參數(shù)傳遞出去
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 異步操作成功 */){
... 異步操作
resolve(value); // 異步操作的結(jié)果作為參數(shù)浆兰,傳遞出去
} else {
reject(error);
}
});
- .then 方法
(1) promise實例生成以后颓哮,可以用.then方法家妆,分別指定resolved狀態(tài) 和 rejected狀態(tài)的回調(diào)函數(shù)
(2) .then方法可以接受 ( 兩個回調(diào)函數(shù) ) 作為參數(shù)冕茅,
===> 第一個回調(diào)函數(shù),在promise對象的狀態(tài)變?yōu)?resolved時調(diào)用 ------ (該回調(diào)函數(shù)在promise構(gòu)造函數(shù)中定義嵌赠,在實例化后,.then方法中調(diào)用 )
===> 第二個回調(diào)函數(shù)姜挺,在promise對象的狀態(tài)變?yōu)?rejected 時調(diào)用 ------ (該回調(diào)函數(shù)在promise構(gòu)造函數(shù)中定義,在實例化后凌箕,.then方法中調(diào)用 )
(3) 第二個回調(diào)是可選的拧篮,可以不提供
(4) 這兩個函數(shù)串绩,都接受 promise對象 傳出的值 作為參數(shù)
promise.then(function(value) {
// success
// 該回調(diào)函數(shù)在promise對象狀態(tài)變?yōu)閞esolved時調(diào)用,參數(shù)是promise對象 resolved時礁凡,傳出的值
}, function(error) {
// failure
});
很重要的一個例子
//很重要的一個例子
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
上面代碼中慧妄,timeout方法返回一個Promise實例,表示一段時間以后才會發(fā)生的結(jié)果塞淹。
過了指定的時間(ms參數(shù))以后窟蓝,Promise實例的狀態(tài)變?yōu)閞esolved,就會觸發(fā)then方法綁定的回調(diào)函數(shù)饱普。
promise新建后會立即執(zhí)行
// promise新建后會立即執(zhí)行
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve(); // 這里沒有傳參运挫,作用是去觸發(fā).then中的回調(diào)函數(shù)
// resovle()函數(shù)的作用,是把promise實例對象的狀態(tài)變?yōu)閞esolved套耕, --------
// 在異步操作成功時調(diào)用滑臊,并將異步操作的結(jié)果作為參數(shù)傳遞出去
// 而當promise實例對象的狀態(tài)變?yōu)?resolved時,就會觸發(fā) .then函數(shù)中的 回調(diào)函數(shù) --------
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise // 注意執(zhí)行順序
// Hi!
// resolved
上面代碼中箍铲,Promise 新建后立即執(zhí)行,所以首先輸出的是Promise鬓椭。
然后颠猴,then方法指定的回調(diào)函數(shù),將在當前腳本所有同步任務(wù)執(zhí)行完才會執(zhí)行小染,所以resolved最后輸出翘瓮。
( 請求圖片 ) https://blog.csdn.net/h1534589653/article/details/77528367
( Image對象 ) https://blog.csdn.net/baihuaxiu123/article/details/53091105
異步加載圖片
componentDidMount() {
function loadImage(url) {
return new Promise((resolve, reject) => {
const image = new Image('400', '200') // 生成image實例對象,寬高
image.onload = () => {
resolve(image) // 加載成功時候裤翩,返回image對象
}
image.onerror = () => {
reject( new Error(`could not load image at ${url}`)) // 加載失敗是報錯
}
image.src = url // 請求的圖片地址
})
}
loadImage('http://pic.7y7.com/201410/2014102458431393_600x0.jpg')
.then(res => {
console.log( res.src ) // 拿到image對象的src 屬性
this.setState({
images: res
},() => {console.log(this.state.images)})
}, () => {
// rejected狀態(tài)下的回掉函數(shù)
})
}
resolve函數(shù)资盅,reject函數(shù) ------------- (重要)
- 如果調(diào)用resolve和reject函數(shù)時,帶有參數(shù)踊赠,那么他們的參數(shù)會傳給回調(diào)函數(shù)
- reject函數(shù) 的 參數(shù)呵扛, 通常是 Error對象的實例,表示拋出的錯誤
- resolve函數(shù)的參數(shù)筐带,除了正常值以外今穿,還可能是另一個promise實例
const p1 = new Promise(function (resolve, reject) {
// ...
});
const p2 = new Promise(function (resolve, reject) {
// ...
resolve(p1); // p2異步操作的結(jié)果返回 --> p1 異步操作
})
上面代碼中,p1和p2都是 Promise 的實例伦籍,
但是p2的resolve方法將p1作為參數(shù)蓝晒,即一個異步操作的結(jié)果是返回另一個異步操作腮出。
----------------------------------------------------
注意: 上面例子中
p1的狀態(tài)決定了p2的狀態(tài)
(1) 如果 p1 的狀態(tài)是pending,那么 p2 的回調(diào)函數(shù)就會等待 p1 的狀態(tài)改變
(2) 如果 p1 的狀態(tài)是 fulfilled或者rejected胚嘲,那么 p2 的回調(diào)函數(shù)將會立即執(zhí)行
Promise嵌套 ---------------------------(重要)(重要)(重要)
componentDidMount() {
let i = 0
setInterval(() => {
console.log(`經(jīng)過了${++i}s`)
},1000)
const p1 = new Promise( (resolve,reject) => {
setTimeout(() => {
reject(new Error('fail'))
console.log('3s') // console.log語句仍然會執(zhí)行馋劈,并且在reject()異步函數(shù) 前執(zhí)行
},3000)
})
const p2 = new Promise( (resolve,reject) => {
setTimeout( () => {
return resolve(p1) // 一般都在這里加return侣滩,這樣后面的代碼就不會執(zhí)行君珠,防止意外2咛怼毫缆!
console.log('1s')
}, 1000 )
})
p2.then(res => console.log(res)) // 并沒有執(zhí)行
.catch(error => console.log(error))
// 注意: p2.then(res => console.log(....))并沒有執(zhí)行苦丁,因為p2的狀態(tài)變成了p1的狀態(tài)旺拉,是rejected
// p2.then(res => console.log(res,'fulfilled'), res => console.log(res,'rejected'))
// 實際執(zhí)行的是上面的 第二個回調(diào)函數(shù)
}
解析:
(1) p1 是一個promise對象蛾狗,3s后狀態(tài)變?yōu)閞ejected
(2) p2 是一個promise對象,狀態(tài)在 1s 后改變谢鹊,但是P2的resolvef方法返回的是p1佃扼,p1是promise對象
導(dǎo)致p2的狀態(tài)由p1決定松嘶,即 p1的狀態(tài)傳遞給p2
(3) P2會等待P1的狀態(tài)改變?yōu)?fulfilled或者reject翠订,P1狀態(tài)改變后,P2的回調(diào)函數(shù)會立刻執(zhí)行 ( --!!!重要!!!-- )
( 所以1s的時候官撼,.then方法并沒有輸出內(nèi)容 )
(并且3s后似谁,p2的狀態(tài)不是fulfilled巩踏,而是 rejeced,即是p1的狀態(tài) )
(4) 又過了2s菠净,p1的狀態(tài)變?yōu)?rejected毅往,導(dǎo)致觸發(fā) .catch 回調(diào)函數(shù)
- 一般來說攀唯,調(diào)用resolve或reject以后侯嘀,Promise 的使命就完成了谱轨,后繼操作應(yīng)該放到then方法里面碟嘴,而不應(yīng)該直接寫在resolve或reject的后面娜扇。所以雀瓢,最好在它們前面加上return語句刃麸,這樣就不會有意外司浪。
Promise.prototype.then() 方法
promise實例有.then方法,是定義在原型對象 Promise.prototype 上的
- then() 方法的作用是為 promise實例添加狀態(tài)改變后的回調(diào)函數(shù)
- then() 方法的參數(shù)是兩個回掉函數(shù)吁伺,第一個是 resolved 狀態(tài)的回調(diào)函數(shù)篮奄,第二個是rejected狀態(tài)的回調(diào)函數(shù) ( 第二個參數(shù)可選窟却,一般都不用,而用 catch()方法捕獲錯誤 )
- then() 方法返回的是新的promise實例菩帝,因此可以采用鏈式寫法
Promise.prototype.then()方法的鏈式調(diào)用---------(重要)
采用鏈式的then胁附,可以指定一組按照次序調(diào)用的回調(diào)函數(shù)控妻。
- 這時弓候,前一個回調(diào)函數(shù)他匪,有可能返回的還是一個Promise對象(即有異步操作)邦蜜,這時后一個回調(diào)函數(shù)悼沈,就會等待該Promise對象的狀態(tài)發(fā)生變化,才會被調(diào)用衣吠。
componentDidMount() {
let i = 0
setInterval(() => {
console.log(`經(jīng)過了${++i}s`)
},1000)
const lian1 = new Promise( (resolve,reject) => {
return setTimeout(() => {
resolve('2s的promise的fulfilled狀態(tài)返回值')
},2000)
})
lian1
.then(res => console.log(res))
.then( res => {
return new Promise( (resolve,reject) => {
return setTimeout(() => {
return reject('3s的promise的rejected狀態(tài)返回值')
},1000)
})
})
.then(res => console.log(res,'reject'), res => console.log(res, 'reject'))
}
// 經(jīng)過了1s
// 經(jīng)過了2s
// 2s的promise的fulfilled狀態(tài)返回值
// 經(jīng)過了3s
// 3s的promise的fulfilled狀態(tài)返回值 reject
// 經(jīng)過了4s
Promise.prototype.catch()
Promise.prototype.catch() 是 .then(null, rejection) 的別名缚俏,用于指定發(fā)生錯誤時的回調(diào)函數(shù)
- 如果promise實例對象的狀態(tài)變?yōu)閞ejected恬惯,就會觸發(fā) catch() 方法指定的回調(diào)函數(shù)
- 如果 .then() 方法指定的回調(diào)函數(shù)在運行中拋出錯誤宿崭,也會被 catch() 方法捕獲
- promise對象的錯誤具有冒泡性質(zhì)才写,會一直向后傳遞赞草,直到被捕獲為止
( 也就是說錯誤總是會被下一個catch語句捕獲 ) - 一般來說厨疙,不要在.then()方法中定義rejected狀態(tài)的回調(diào)函數(shù),而總是使用 .catch()方法
- 一般總是建議梗醇,promise對象后要跟 catch()方法叙谨,這樣可以處理 promise內(nèi)部發(fā)生法的錯誤手负,catch() 方法返回的還是promise對象竟终,因此后面還可以接著調(diào)用 then() 方法
- catch() 方法中還能再拋錯誤统捶,如果 catch()方法拋出錯誤后柄粹,后面沒有catch()方法镰惦,錯誤就不會被捕獲旺入,也不會傳遞到外層。
如果catch()方法拋出錯誤后礼华,后面有then()方法圣絮,會照常執(zhí)行扮匠,后面有catch()方法棒搜,錯誤還會被再一次捕獲
p.then((val) => console.log('fulfilled:', val))
.catch((err) => console.log('rejected', err));
// 等同于
p.then((val) => console.log('fulfilled:', val))
.then(null, (err) => console.log("rejected:", err));
例子
getJSON('/post/1.json')
.then(function(post) {
return getJSON(post.commentURL);
})
.then(function(comments) {
// some code
})
.catch(function(error) {
// 處理前面三個Promise產(chǎn)生的錯誤
});
上面代碼中力麸,一共有三個 Promise 對象:一個由getJSON產(chǎn)生克蚂,兩個由then產(chǎn)生埃叭。
它們之中任何一個拋出的錯誤游盲,都會被最后一個catch捕獲益缎。
promise.prototype.finally()
promise.prototype.finally()方法用于指定不管promise對象最后的狀態(tài)如何莺奔,都會執(zhí)行的操作
- finally() 方法的回調(diào)函數(shù)令哟,不接受任何參數(shù)妨蛹。
( 這就意味著蛙卤,無法知道前面pormise實例對象最后的狀態(tài)是fulfilled還是rejected噩死,也就是說已维,finally()函數(shù)中的操作與狀態(tài)無關(guān)垛耳,不依賴promise對象執(zhí)行的結(jié)果 ) - finally總是會返回之前的值
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
上面代碼中堂鲜,不管promise最后的狀態(tài)泡嘴,在執(zhí)行完then或catch指定的回調(diào)函數(shù)以后酌予,
都會執(zhí)行finally方法指定的回調(diào)函數(shù)抛虫。
Promise.all() -------- 注意建椰,不在原型對象上
Promise.all() 方法用于將多個promise實例棉姐,包裝成一個新的promise實例
- promise.all() 方法的參數(shù)可以不是數(shù)組伞矩,但是必須具有 iterator 接口乃坤,且返回的每個成員都是promise實例 ( 具有iterator接口湿诊,就是可遍歷的數(shù)據(jù)結(jié)構(gòu)厅须,可以被 for...of 遍歷 )
- 注意:如果作為參數(shù)的promise實例
( 即Promise.all()實例子是rejected狀態(tài) )
自己定義了catch()方法朗和,就不會觸發(fā)Promise.all()實例的 catch() 方法
const p = Promise.all( [p1, p2, p3] );
上面代碼中例隆,promise.all()方法镀层,接受一個數(shù)組作為參數(shù)唱逢,p1, p2, p3都是promise實例
promise.all() 方法的參數(shù)可以不是數(shù)組屋休,但是必須具有 iterator 接口
p的狀態(tài)由 p1, p2, p3決定,分兩種情況
(1) 只有p1,p2,p3的狀態(tài)都變?yōu)?fulfilled痪枫, p的狀態(tài)才會變?yōu)?fulfilled
此時,p1,p2,p3的返回值組成一個數(shù)組吃粒,傳遞給p的回調(diào)函數(shù)
(2) 只要p1,p2,p3中有一個被 rejected徐勃,p的狀態(tài)就變成rejected
此時僻肖,第一個被rejected的實例的返回值檐涝,會傳給p的回調(diào)函數(shù)
例子
情況1:
// a,b,c都是promise實例對象
// 當a,b,c都是fulfilled狀態(tài)時谁榜, p 才是fulfilled狀態(tài)窃植,才會觸發(fā)then的resolved狀態(tài)的回調(diào)函數(shù)
// p 的回調(diào)函數(shù)的參數(shù),是a,b,c都變?yōu)閞esolved狀態(tài)時的返回值組成的數(shù)組
componentDidMount() {
let a = new Promise((resolve, reject) => {
return resolve(1)
})
let b = new Promise((resolve,reject) => {
return resolve(2)
})
let c = new Promise((resolve,reject) => {
return resolve(3)
})
const p = Promise.all([a,b,c]) // a,b,c都是promise實例對象
p.then(res => console.log(res)) // 輸出 [1, 2, 3]
}
情況2:
// a,b,c都是promise實例對象
// 當a,b,c中有一個是rejected狀態(tài)時荐糜,p的狀態(tài)就是rejected狀態(tài)巷怜,
// p 的回調(diào)函數(shù)的參數(shù)葛超,是最先被rejected的Promse實例的返回值
componentDidMount() {
let a = new Promise((resolve, reject) => {
// return resolve(1)
return reject(new Error('錯誤來自promise----a'))
})
let b = new Promise((resolve,reject) => {
// return resolve(2)
return reject(new Error('錯誤來自promise----b'))
})
let c = new Promise((resolve,reject) => {
return resolve(3)
})
const p = Promise.all([a,b,c]) // p是rejected時,p的回調(diào)函數(shù)的參數(shù)是最先rejected的實例返回值
p.then(res => console.log(res))
.catch(err => console.log(err)) // 輸出 Error: 錯誤來自promise----a
}
特殊情況
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('報錯了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 報錯了]
上面代碼中延塑,p1會resolved绣张,p2首先會rejected,
但是p2有自己的catch方法关带,該方法返回的是一個新的 Promise 實例侥涵,p2指向的實際上是這個實例嗦明。
該實例執(zhí)行完catch方法后,也會變成resolved裙戏,導(dǎo)致Promise.all()方法參數(shù)里面的兩個實例都會resolved壹罚,
因此會調(diào)用then方法指定的回調(diào)函數(shù)绪穆,而不會調(diào)用catch方法指定的回調(diào)函數(shù)。
Promise.race() --------- 對比Promise.all()
Promise.race()方法的作用同樣是將多個promise對象實例包裝成新的promise實例
- race是賽跑,率先的意思
- 規(guī)則: 如果p1, p2, p3 中實例對象的狀態(tài)有一個率先改變键袱, p的狀態(tài)就會跟這改變 ( 無論是變?yōu)閒ulfilled狀態(tài)付鹿,還是變?yōu)?rejected狀態(tài) )纽匙,p的回調(diào)函數(shù)的參數(shù),是最先改變的那個promise實例的返回值
const p = Promise.race([ // Promise.race() 只要有一個參數(shù)狀態(tài)改變,p的狀態(tài)就是跟著改變
fetch('/resource-that-may-take-a-while'), // fetch返回的是promise對象
new Promise(function (resolve, reject) { // 5s后變?yōu)閞ejected狀態(tài)
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
解析:
fetch在5s鐘內(nèi)請求成功,p變成fulfilled狀態(tài),觸發(fā)p的then()方法
fetch在5s中內(nèi)請求失敗,p變?yōu)閞ejected狀態(tài)碌尔,觸發(fā)p的catch()方法
Promise.resolve()
promise.resolve()可以將對象轉(zhuǎn)換為promise對象
- promise.resolve('foo') 等價于
new Promise(resolve => resolve('foo'))
Promise.resolve('foo')
// 等價于
new Promise(resolve => resolve('foo'))
Promise.resolve()方法的 參數(shù)
總結(jié):
Promise.resolve()的參數(shù)無論是什么類型 ( 或者不帶參數(shù)颈走,或者參數(shù)本來就是一個promise對象,或者參數(shù)是一個thenable對象,或者參數(shù)是原始值而柑,或者參數(shù)是普通對象 )本質(zhì)上Promise.resolve()都會把參數(shù)轉(zhuǎn)化為Promise對象,只是狀態(tài)分情況而已妙同,比如:如果參數(shù)是thenable對象芒涡,會立即執(zhí)行thenable對象的then方法依啰,狀態(tài)當然后then方法中的函數(shù)決定速警,從而決定Promise.resolve()返回的promise對象的狀態(tài)
Promise.resolve()方法的參數(shù)分為四種情況
- 參數(shù)是一個promise實例對象
如果Promise.resolve()方法的參數(shù)是一個( 實例對象 ),那么Promise.resolve()方法將原封不動的( 返回這個實例對象 )
componentDidMount() {
const foo = new Promise( (resolve, reject) => {
return resolve('foo是一個promise實例對象')
})
const p = Promise.resolve(foo) // Promise.resolve()的參數(shù)是一個promise實例
console.log( p );
// 輸出: Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "foo是一個promise實例對象"}
}
- 參數(shù)是一個thenable 對象
如果Promise.resolve()方法的參數(shù)是 ( thenable對象 ),那么Promise.resolve()方法會將這個對象轉(zhuǎn)化為promise對象双妨,然后立刻執(zhí)行 thenable對象的 then 方法
什么是 thenable 對象 挑随?
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
// 如果Promise.resolve()的參數(shù)是 thenable對象, Promise.resolve()方法會把thenable對象轉(zhuǎn)化為promise對象
// 然后立刻執(zhí)行thenable對象的then方法
componentDidMount() {
const thenable = { // thenable對象,里面有then方法
then: (resolve,reject) => resolve('這是thenable對象')
}
Promise.resolve(thenable) // 參數(shù)是thenable對象疚察,立刻執(zhí)行thenable對象的then方法
.then(res => console.log(res)) // thenable對象的的狀態(tài)是fulfilled,輸出其返回值
}
// 輸出:這是thenable對象
- 參數(shù)不是thenable對象,或者根本不是一個對象
如果參數(shù)是一個原始類型的值( 數(shù)字堤撵,字符串,布爾值 ),或者是一個不具有then方法的對象,則Promise.resolve()方法返回一個新的promise對象,狀態(tài)是fulfilled
componentDidMount() {
const str = 'abc'
const foo = Promise.resolve(str)
// 參數(shù)是原始類型的值吉挣,Promise.resolve()方法會返回一個promise對象氯哮,狀態(tài)是resolved
foo.then(res => console.log(res)) // 所以該回調(diào)會執(zhí)行
}
- 不帶參數(shù)
當Promise.resolve()方法不帶參數(shù)是出牧,直接返回一個promise對象,狀態(tài)是resolved
Promise.reject()方法
Promise.reject()方法返回一個promise實例對象,狀態(tài)是rejected
- 和Promise.resolve()類似想暗,只是Promise.rejected()方法的狀態(tài)一定是rejected
const p = Promise.reject('出錯了');
p.then(null, function (s) {
console.log(s)
});
// 出錯了
// 等同于
const p = new Promise((resolve, reject) => reject('出錯了'))
p.then(null, function (s) {
console.log(s)
});
// 出錯了
promise對象的應(yīng)用
Promise.try()
const f = () => console.log('now'); // 函數(shù)f是一個同步事件
Promise.resolve().then(f); // 通過Promise.resolve()返回一個promise對象捣郊,狀態(tài)是resolved僧凤,f變成異步
console.log('next');
// next 所以會先輸出next躯保,再輸出now
// now
如何讓同步函數(shù)同步執(zhí)行义图,異步函數(shù)異步執(zhí)行历筝,并且讓他們具有統(tǒng)一的api呢蜘渣?
-
(1) 使用async函數(shù)
await 操作符用于等待一個 Promise 對象, 它只能在異步函數(shù) async function 內(nèi)部使用.
componentDidMount() {
const funSync1 = () => console.log('我是同步函數(shù)1111111')
const funSync2 = () => console.log('我是同步函數(shù)2222222')
const funAsync = async () => { // async關(guān)鍵字蔫缸,定義的函數(shù)是異步函數(shù),返回promise對象
await funSync1()
}
funAsync().then(funSync2())
console.log('bbbb')
}
// 先把兩個同步函數(shù)變成了異步际起,在異步函數(shù)中拾碌,先執(zhí)行funSync1,后執(zhí)行funSync2
// 使用async關(guān)鍵字后街望,會把同步包裝成的異步函數(shù)校翔,按同步方式執(zhí)行
// 所以最后得到的輸出順序是:
// 我是同步函數(shù)1111111
// 我是同步函數(shù)2222222
// bbbb
-
(2) 使用 new Promise()
const f = () => console.log('now');
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log('next');
// now
// next
-
(3) Promise.try() 提案
const f = () => console.log('now');
Promise.try(f);
console.log('next');
// now
// next