乐趣区

关于javascript: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 再执行。

如何能够解决这种问题?

将 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 进行改良

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 学习幅员

退出移动版