Promise與非同步程式設計
建立一個待執行狀態的Promise
new Promise()會立即執行,因此如果需要在合適的位置建立Promise,可以使用一個函式進行包裝,合適的位置進行呼叫
let fs = require('fs')
function readFile(fileName){
return new Promise((resolve, reject) => {
//非同步操作
fs.readFile(fileName, (err, contents)=> {
//讀取錯誤時
if(err){
reject(err)
return;
}
//讀取成功時
resolve(contents)
})
})
}
let file = readFile('readme.txt')
// 同時監聽成功或失敗
file.then(data =>{
},err=>{
})
複製程式碼
直接返回一個已執行狀態的Promise物件
Promise.resolve()
Promise.reject()
複製程式碼
- 傳遞給Promise.resolve()的引數,如果是一個Promise物件,則會原樣返回,如果不是一個Promise物件,針對非Promise的thenable物件,會做進一步包裝,將其轉換成Promise物件再返回(基本型別的值也會被自動轉換成Promise物件)
- 非Promise的thenable物件:具有接受resolve、reject引數的then()方法的物件
上例中 1.程式按順序執行,遇到let thenable = { then(resolve,reject){ console.log('enter thenable') resolve(42) } } let p1 = Promise.resolve(thenable) console.log('before then') p1.then(data =>{ console.log(data) }).catch(err => { console.log(err) }) /* before then enter thenable 42 */ 複製程式碼
Promise.resolve(thenable)
時會把thenable中的then()中的非同步函式放入microtask佇列中,等主程式執行完後呼叫 2. 執行console.log('before then')
3. 執行p1.then()這裡,監聽p1的狀態,一旦由pending變為resolve或reject,便將其放入microtask佇列中,在主程式執行完後執行 4. 因此先列印before then
,然後再列印enter thenable
,最後是42
then()、catch()執行完後都會返回一個Promise物件,如果沒有顯式指定return,則會返回一個預設的Promise
響應多個Promise
-
Promise.all([, , ,])引數是一個可迭代的物件(常用陣列),每個元素都是Promise物件
let p1 = new Promise((resolve, reject) => { resolve('p1') }) let p2 = new Promise((resolve, reject) => { resolve('p2') }) let p3 = new Promise((resolve, reject) => { resolve('p3') }) let p4 = Promise.all([p1, p2, p3]) p4.then(value => { console.log(Array.isArray(value)) //true console.log(value) //["p1", "p2", "p3"] }) 複製程式碼
Promise.all([]).then()
then()中的引數是一個陣列,成員是你傳入的多個Promise物件中resolve的值let p1 = new Promise((resolve, reject) => { resolve('p1') }) let p2 = new Promise((resolve, reject) => { reject('p2') }) let p3 = new Promise((resolve, reject) => { resolve('p3') }) let p4 = Promise.all([p1, p2, p3]) p4.then(value => { console.log(Array.isArray(value)) //true console.log(value) //["p1", "p2", "p3"] }).catch(err => { console.log('err',err) } ) 複製程式碼
如果Promise物件中觸發reject狀態,則會立即觸發
Promise.all([]).catch()
catch()中的引數是觸發reject()返回的值 -
Promise.race([, , ,]) 多個Promise物件競賽,誰先觸發狀態變化,立刻停止
let p1 = new Promise((resolve, reject) => { resolve('p1') }) let p2 = Promise.resolve('p2') let p3 = new Promise((resolve, reject) => { resolve('p3') }) let p4 = Promise.race([p1, p2, p3]) p4.then(value => { console.log(value) }).catch(err => { console.log('err',err) }) // p1 複製程式碼