為什麼需要promise
- 回撥地獄 如果多個非同步請求 有連帶關係 回撥巢狀
- 多個非同步實現併發的話,會出現無法同步非同步的返回結果
- 錯誤處理不方便
什麼是promise(承諾)
- promise 有三個狀態 (成功態 Resolved 失敗態 Rejected 等待態 Pending)
- 預設情況下 狀態轉換(狀態不可逆)
- pending -> resolved
- pending -> rejected
- resolved 不能和rejected相互轉換
- 用法:promise在ie下是不相容的(可以使用webpack的polyfill等方式解決)
// new Promise的時候 需要傳遞一個executor執行器,執行器函式會預設被內部所執行
new Promise(function(resolve,reject){
// 如果在這裡呼叫了resolve 就會變成成功態
console.log('hello') // 第一個執行
})
console.log('hello1') // 第二個執行
複製程式碼
let p = new Promise(function(resolve.reject){
resolve();
})
// 每個promise(例項)都有一個then方法
// then方法是一個非同步方法,預設不會再當前的上下文中執行(微任務)且比setTimeout先執行
p.then(function(){
console.log('成功')
},function(){
console.log('失敗')
})
複製程式碼
// 面試題
setTimeout(function(){
console.log(1)
},0)
new Promise(function(resolve){
console.log(2)
for(var i = 0;i<10;i++){
i==9 && resolve()
}
console.log(3)
}).then(function(){
console.log(4)
})
console.log(5)
// 2 3 5 4 1
複製程式碼
promise解決非同步的基本使用
- promise 每次呼叫then後,分下面幾種情況
- 如果返回的是promise 用promise的成功或者失敗 執行下一個then
- 如果返回的是一個普通值(包括不寫return,預設return undefined)會走外層下一個then的成功
- 如果執行的時候,丟擲異常就會走到下一個then中的失敗
- then中可以不傳遞引數,如果不傳遞 會透到下一個then中
- catch用來捕獲錯誤的,相當於then的第一個引數傳遞null catch之後仍然可以繼續then
let fs = require('fs')
function read(file){
return new Promise(function(resolve,reject){
fs.readFile(file,'utf8',function(err,data){
if(err) reject(err)
resolve(data)
})
})
}
// promise的鏈式呼叫
read('./name.txt').then(function(data){
// then方法成功後 返回的是一個新的promise 這個返回的promise會被執行,如果返回的promise是成功的,會把這個結果傳遞到外層的下一個then中
// return read(data) 返回下一個then成功
// throw new Error('出錯了') 返回下一個then失敗
return data // 返回下一個then成功
},function(err){
console.log(err)
}).then(function(data){
console.log('age',data)
}).then().catch(function(err){
console.log('error',err)
}).then(function(data){
console.log(data)
})
複製程式碼
// 面試題
new Promise(function(resolve,reject){
resolve(1)
})
.then(function(data){
console.log(data)
return 2;
})
.catch(function(err){
return 3;
})
.then(function(res){
console.log(res)
})
// 1 2
複製程式碼
Promise.all(promise提供了一個 併發的方法 Promise.all 返回的結果是一個promise,只有傳遞的promise陣列全部成功才會返回成功態)
Promise.all([read('./name.txt'),read('./age.txt')]).then(function(data){
console.log(data)
}).catch(function(err){
console.log(err)
})
複製程式碼
Promise.race(只要有一個返回成功 就返回成功態)
Promise.race([read('./name.txt'),read('./age.txt')]).then(function(data){
console.log(data)
}).catch(function(err){
console.log(err)
})
複製程式碼