qappleh / Interview

我是追梦赤子心,公众号「深圳湾码农」的作者,某上市集团公司高级前端开发,深耕前端领域多年,每天攻破一道题,带你从0到1系统构建web全栈完整的知识体系!
https://github.com/qappleh/Interview
1.14k stars 95 forks source link

第314题(2020-09-27):异步串行编程题:按照以下要求,实现 createFlow 函数(阿里) #317

Open qappleh opened 3 years ago

qappleh commented 3 years ago
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const subFlow = createFlow([() => delay(1000).then(() => console.log("c"))]);

createFlow([
  () => console.log("a"),
  () => console.log("b"),
  subFlow,
  [() => delay(1000).then(() => console.log("d")), () => console.log("e")],
]).run(() => {
  console.log("done");
});

// 需要按照 a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印

按照上面的测试用例,实现 createFlow:

qappleh commented 3 years ago

方法一:function

function createFlow(effects = []) {
  const queue = [...effects.flat()]
  const run = async function(cb) {
    for(let task of queue) {
      if(task.isFlow) {
        await task.run()
      } else {
        await task()
      }
    }
    if(cb) cb()
  }
  return {
    run,
    isFlow: true
  }
}

// 测试
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const subFlow = createFlow([() => delay(1000).then(() => console.log("c"))]);

createFlow([
  () => console.log("a"),
  () => console.log("b"),
  subFlow,
  [() => delay(1000).then(() => console.log("d")), () => console.log("e")],
]).run(() => {
  console.log("done");
});

// a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印
class
class Flow {
  constructor(effects) {
    this.queue = [...effects.flat()]
  }
  async run(cb) {
    for(let task of this.queue) {
      if(task instanceof Flow) {
        await task.run()
      } else {
        await task()
      }
    }
    if(cb) cb()
  }
};

function createFlow(effects = []) {
    return new Flow(effects)
};

// 测试
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const subFlow = createFlow([() => delay(1000).then(() => console.log("c"))]);

createFlow([
  () => console.log("a"),
  () => console.log("b"),
  subFlow,
  [() => delay(1000).then(() => console.log("d")), () => console.log("e")],
]).run(() => {
  console.log("done");
});
// a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印
参考:[function
function createFlow(effects = []) {
  const queue = [...effects.flat()]
  const run = async function(cb) {
    for(let task of queue) {
      if(task.isFlow) {
        await task.run()
      } else {
        await task()
      }
    }
    if(cb) cb()
  }
  return {
    run,
    isFlow: true
  }
}

// 测试
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const subFlow = createFlow([() => delay(1000).then(() => console.log("c"))]);

createFlow([
  () => console.log("a"),
  () => console.log("b"),
  subFlow,
  [() => delay(1000).then(() => console.log("d")), () => console.log("e")],
]).run(() => {
  console.log("done");
});

// a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印

方法二:class

class Flow {
  constructor(effects) {
    this.queue = [...effects.flat()]
  }
  async run(cb) {
    for(let task of this.queue) {
      if(task instanceof Flow) {
        await task.run()
      } else {
        await task()
      }
    }
    if(cb) cb()
  }
};

function createFlow(effects = []) {
    return new Flow(effects)
};

// 测试
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const subFlow = createFlow([() => delay(1000).then(() => console.log("c"))]);

createFlow([
  () => console.log("a"),
  () => console.log("b"),
  subFlow,
  [() => delay(1000).then(() => console.log("d")), () => console.log("e")],
]).run(() => {
  console.log("done");
});
// a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印

参考:https://juejin.im/post/6860646761392930830