es6學習4:async和await

async異步

async函數返回一個 Promise 對象,能夠使用then方法添加回調函數。當函數執行的時候,一旦遇到await就會先返回,等到異步操做完成,再接着執行函數體內後面的語句。async

function setNumAdd(n) {
            return new Promise((resolve,reject) =>{
                setTimeout( ()=>{
                    n +=1;
                    resolve(n)
                },1000)
            })
        }

        function setNumSub(n) {
            return new Promise((resolve,reject) =>{
                setTimeout( ()=>{
                    n -=1;
                    resolve(n)
                },1000)
            })
        }

        async function d(n) {
            const w1 = await setNumAdd(n);
            const w2 = await setNumSub(n);
            return w1+w2
        }
        d(10).then( v=>{
            console.log(v)  //10
        })

 

async函數返回一個 Promise 對象。async函數內部return語句返回的值,會成爲then方法回調函數的參數。函數

async function f() {
  return 'hello world';
}

f().then(v => console.log(v))
// "hello world"

 

async函數內部拋出錯誤,會致使返回的 Promise 對象變爲reject狀態。拋出的錯誤對象會被catch方法回調函數接收到。spa

async function f() {
  throw new Error('出錯了');
}

f().then(
  v => console.log(v),
  e => console.log(e)
)

//等同於 f().then( v=> console.log(v)).catch( e=>console.log(e))
// Error: 出錯了

 

awaitcode

正常狀況下,await命令後面是一個 Promise 對象,返回該對象的結果。若是不是 Promise 對象,就直接返回對應的值。對象

async function f() {
  // 等同於
  // return 123;
  return await 123;
}

f().then(v => console.log(v))
// 123

 

任何一個await語句後面的 Promise 對象變爲reject狀態,那麼整個async函數都會中斷執行。blog

async function f() {
  await Promise.reject('出錯了');
  await Promise.resolve('hello world'); // 不會執行
}

上面代碼中,第二個await語句是不會執行的,由於第一個await語句狀態變成了rejectget

有時,咱們但願即便前一個異步操做失敗,也不要中斷後面的異步操做。這時能夠將第一個await放在try...catch結構裏面,這樣無論這個異步操做是否成功,第二個await都會執行。回調函數

async function f() {
  try {
    await Promise.reject('出錯了');
  } catch(e) {
  }
  return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))
// hello world

另外一種方法是await後面的 Promise 對象再跟一個catch方法,處理前面可能出現的錯誤it

async function f() {
  await Promise.reject('出錯了')
    .catch(e => console.log(e));
  return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))
// 出錯了
// hello world
錯誤處理

 

 

若是有多個await命令,能夠統一放在try...catch結構中。

async function main() {
  try {
    const val1 = await firstStep();
    const val2 = await secondStep(val1);
    const val3 = await thirdStep(val1, val2);

    console.log('Final: ', val3);
  }
  catch (err) {
    console.error(err);
  }
}

 

let foo = await getFoo();
let bar = await getBar();

多個await命令後面的異步操做,若是不存在繼發關係,最好讓它們同時觸發。

上面代碼中,getFoogetBar是兩個獨立的異步操做(即互不依賴),被寫成繼發關係。這樣比較耗時,由於只有getFoo

完成之後,纔會執行getBar,徹底能夠讓它們同時觸發。

// 寫法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);

// 寫法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;
相關文章
相關標籤/搜索