面试题目(字节)——异步顺序处理数据

面试题目(字节)——异步顺序处理数据

场景

​ 一个问题自己过程中想了很长时间没有解决出来,特此记录一下

let timeout = (ms) => {
  return new Promise(resolve => {
    setTimeout(resolve, ms)
  })
}


let ajax1 = () => timeout(2000).then(data => {
  console.log('1')
  return 1
})

let ajax2 = () => timeout(1000).then(data => {
  console.log('2')
  return 2
})
let ajax3 = () => timeout(500).then(data => {
  console.log('3')
  return 3
})

promiseArr([ajax1, ajax2, ajax3]).then(data => {
  console.log('done')
  console.log(data)
})

// 希望数据顺序执行为 '1', '2', '3', 'done', [1, 2, 3]

这个问题开始看的时候就知道肯定是顺序异步执行 ajax1 -> ajax2 -> ajax3, 但是这个return把我卡住了。之后好好看了看Promise 执行then方法仍然可以执行 then,一下子豁然开朗,测试代码如下

let p = new Promise(resolve => {
  resolve()
})
console.log(p) // Promise { undefined }
let testPromise = p.then(data => console.log('1'))
console.log(testPromise) // Promise { <pending> }
testPromise.then(data => console.log(1)) // 1

testPromise仍然是一个promise对象,仍然后边可以跟then,既然是promise,就可以使用async,await 来优雅解决这个问题

const promiseArr =  (ajaxArr) => {
  return new Promise(async resolve => {
    let arr = [];
    for(let ajax of ajaxArr) {
      let data = await ajax()
      arr.push(data)
    }
    resolve(arr)
  })
}

不用async,await的话也可以用递归来处理

const promiseArr = (ajaxArr) => {
  return new Promise(resolve => {
    let arr = [], i = 0
    const next = () => {
      ajaxArr[i]().then(data => {
        i ++;
        arr.push(data)
        if(i < ajaxArr.length) {
          next()
        }else {
          resolve(arr)
        }
      })
    }
    next()
  })
}

读文档时发现也可以利用reduce 方法来处理,需要为初始值赋值Promise.resolve(),实现如下

const promiseArr = (ajaxArr) => {
  return new Promise(resolve => {
    let arr = []
    ajaxArr.reduce((start, nextPromise) => {
      return start.then(nextPromise).then(data => {
        arr.push(data)
        if(arr.length === ajaxArr.length) {
          resolve(arr)
        }
      })
    }, Promise.resolve())
  })
}

第一种方式是最优雅的

小结

​ 归根结底这都是事后诸葛亮,还是因为自己对基础的掌握不足而在面试中没有解决出这个问题,还是要多多努力,继续冲!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值