Interview icon indicating copy to clipboard operation
Interview copied to clipboard

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

Open qappleh opened this issue 5 years ago • 1 comments

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:

  • flow 是指一系列 effects 组成的逻辑片段。
  • flow 支持嵌套。
  • effects 的执行只需要支持串行。

qappleh avatar Sep 27 '20 01:09 qappleh

方法一: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

qappleh avatar Oct 09 '20 08:10 qappleh