非同步解決方案---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) }) 複製程式碼