ES9(一) —— For await of

目錄

  • 問es9中異步操做集合是如何遍歷的?
  • 如何能夠解決這種問題?
  • 最終的解決方式-for-await-of
  • for-of和for-await-of的區別
  • 自定義數據結構的異步遍歷如何實現?
  • ES6-ES10學習版圖

問:ES9中異步操做集合是如何遍歷的?

數組中的元素都是promise對象,那麼是沒有辦法遍歷的。數組

function Gen(time) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve(time)
    },time)
  })
}

function test() {
  let arr = [Gen(2000), Gen(1000), Gen(3000)]
  for(let item of arr) {
    console.log(Date.now(), item.then(console.log))
  }
}

test()
// 1597047404040 Promise {<pending>}
// 1597047404040 Promise {<pending>}
// 1597047404040 Promise {<pending>}
// 1000
// 2000
// 3000

這種遍歷就是無論三七二十一,首先遍歷出來,而後掛起的promise再執行。promise

如何能夠解決這種問題?

將test函數前面添加async,並在for-of遍歷的時候給每一個元素前面添加await,每一個對象等待結束以後再執行下一個。數據結構

function Gen(time) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve(time)
    },time)
  })
}

async function test() {
  let arr = [Gen(2000), Gen(1000), Gen(3000)]
  for(let item of arr) {
    console.log(Date.now(), await item.then(console.log))
  }
}

test()

// 2000
// 1597047766221 undefined
// 1000
// 1597047768223 undefined
// 3000
// 1597047768224 undefined
分析輸出結果:先執行了 await後面的 then,返回 2000以後
執行 console.log返回時間戳
而後 await的返回值是空,因此返回 undefined
雖然由於 awaitfor-of暫停了,可是執行的順序和咱們想要的仍是不同

最終的解決方式 —— For await of

test函數前面還要添加async關鍵字,對for-of進行改進dom

function Gen(time) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve(time)
    },time)
  })
}

async function test() {
  let arr = [Gen(2000), Gen(100), Gen(3000)]
  for await(let item of arr) {
    console.log(Date.now(), item)
  }
}

test()

// 1597048677429 2000
// 1597048677429 100
// 1597048678429 3000

for-of和for await of的區別

for-of是用來遍歷同步操做的
for-of裏面用 await,若是有其餘操做,也會有輸出順序錯誤
for await of 是能夠對異步集合進行操做

自定義數據結構的異步遍歷如何實現?

  • 定義一個對象,裏面有基礎數據類型,還有promise類型
  • 自定義一個[Symbol.asyncIterator]方法讓其變成可遍歷的對象
  • 使用for await of方法進行遍歷
const obj = {
  count: 0,
  Gen(time) {
    return new Promise((resolve, reject) => {
      setTimeout(function () {
        resolve({ done: false, value:time })
      }, time)
    })
  },
  [Symbol.asyncIterator] () {
    let self = this
    return {
      next() {
        self.count++
        if(self.count < 4) {
          return self.Gen(Math.random() * 1000) //retuen的返回值是Gen函數的resolve返回的對象
        }else{
          return Promise.resolve({
            done: true,
            value: ''
          })
        }
      }
    }
  }
}

async function test () {
  for await (let item of obj) {
    console.log(Date.now(), item)
  }
}

test()

// 1597049702437 292.73328473812523
// 1597049702574 136.72074104961163
// 1597049703250 675.518962144079

ES6-ES10學習版圖

ES6-10.png

相關文章
相關標籤/搜索