爲何須要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)
})
複製代碼