是看的尤雨溪写的代码,觉得这个思路十分巧妙,自己用 es6 凭记忆记录一下。问题描述并不准确,具体问题请看问题链接点我

问题描述

存在一个 api:function getValueFromRemote(index: number, cb: (value: number) => void),是一个异步函数,现需要将 0 ~ 30 这 31 个参数分别传入该函数,并最后顺序打印结果。

递归解法

最容易想到的就是递归解法,即串行调用,先调用 0,0 返回以后在回调函数中继续调用 1,代码如下:

const count = 30;
function _getValue(i: number) {
  getValueFromRemote(i, (value) => {
    printResult(value);
    if (i <= count) {
      _getValue(i + 1);
    }
  });
}

function printResult(value: number) {
  console.log("The value is " + value);
}

_getValue(0)

优点是逻辑简单易懂,缺点就是串行效率太低

数组法

顾名思义就是用数组来存储返回的结果,代码如下:

const apiValue = [];
function _getValue(i: number) {
  getValueFromRemote(i, (value) => {
    apiValue[i] = {
      value,
      printed: false,
    };
    if (i == 0 || apiValue[i - 1].printed) {
      printResult(i);
    }
  });
}

function printResult(index: number) {
  console.log("The value is " + apiValue[index].value);
  apiValue[index].printed = true
  if (
    exist(apiValue[index + 1]) &&
    !apiValue[index + 1].printed
  ) {
    printResult(index + 1);
  }
}

function exist(thing: any) {
  return thing !== undefined && thing !== null;
}

for (let i = 0; i < 31; i++) {
  _getValue(i)
}

以上就是数组法的基本思想,即并发地先执行函数,将返回的结果先记录在对应顺序的数组中,通过判断前后的请求是否被打印来判断自己是否需要被打印。

思路十分清晰简洁,可能对于算法大佬来说这是非常简单的操作,但是我第一次看见这个算法的时候感觉还是感叹自己的能力不够。

同理在面试时经常问到的如何保证异步操作顺序执行其实从这里可以得到借鉴。


LhrAlander
20 声望1 粉丝