Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端怎么每隔1秒渲染一部分数据 #10

Open
tanxin03 opened this issue Nov 3, 2020 · 0 comments
Open

前端怎么每隔1秒渲染一部分数据 #10

tanxin03 opened this issue Nov 3, 2020 · 0 comments

Comments

@tanxin03
Copy link
Owner

tanxin03 commented Nov 3, 2020

  • 工作当中,我们可能会遇到这种情况,后端给前端返回几百条数据,要前端自己渲染,如果前端直接渲染到浏览器,就会卡得你不要不要得。
  • 这个时候,有想法的玩家就有了一些想法,前端可以每隔1秒加载,先加载可视区域,这种方式可行不
function test() {
 let arr = [1, 2, 3]
 arr.forEach(async item => {
  const res = await fetch(item)
  console.log(res)
 })
 console.log('end')
}
 
function fetch(x) {
 return new Promise((resolve, reject) => {
     resolve(x)
 })
}
test()
  • 以上代码, 按照我们的理解是 打印 1 2 3 ‘end’ 实际上是先打印 ‘end’ 1 2 3, 这是为什么呢。
原因如下:
  1. 首先这是因为foreach是没有return返回值的(可以自己去跟下源码,foreach内部实现只是简单的回调)
  2. 而foreach里面的回调函数因为加了async的原因,所以默认会返回一个promise,但是因为foreach的实现并没有返回值,所以导致返回的这个promise对象没人去管了

为了保证 ‘end’ 最后输出,我们肯定要先等待循环的返回结果因此改成如下代

async function test() {
 let arr = [1, 2, 3]
 await arr.forEach(async item => {
  const res = await fetch(item)
  console.log(res)
 })
 console.log('end')
}

但是这样改之后依然行不通,原因是foreach没有返回值,所以我们必须保证循环能够有返回值,所以要将foreach改成map

async function test() {
 let arr = [1, 2, 3]
 await arr.map(async item => {
  const res = await fetch(item)
  console.log(res)
 })
 console.log('end')
}

结果依然不行,然后我们会发现其实map返回的并不是一个promise对象,而是一个包含promise对象的数组[promise, promise, promise],其中每个promise对象都是循环迭代产生的结果。而await是处理不了数组的,它只能处理promise对象。考虑到这一点我们基本上就差不多知道如何改正了、有两种方法。

第一是将循环改成常规的遍历方式

async function test() {
 let arr = [1, 2, 3]
 for(let i in arr){
   const res = await fetch(arr[i])
   console.log(res)              
 }
 console.log('end')
}

第二种就比较高端了,使用Promise.all(),这是一个专门处理promise数组的方法,当async标记的箭头函数返回一个promise对象时,map方法得到的就是一个promise对象数组,然后我们将这个数组丢给Promise.all()去依次执行,然后只需要使用await去等待执行结果,就能保证后面的end在得到结果后才会被输出,得到最终输出结果1,2,3,end

async function test() {
 let arr = [1, 2, 3]
 await Promise.all(arr.map(async item => {
  const res = await fetch(item)
  console.log(res)
 }))
 console.log('end')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant