異步解決方案---promise

爲何須要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)
    }) 
複製代碼
相關文章
相關標籤/搜索