记录LazyMan实现

131 阅读1分钟
function LazyManRun(name, logFn) {
  const taskList = [
    {
      fn: 'lazyMan',
      args: [name],
    }
  ];

  const subscribe = (fn, ...args) => {
    const task = {
      fn,
      args: [...args],
    }

    if (fn === 'sleepFirst') {
      taskList.unshift(task);
    } else {
      taskList.push(task);
    }
  }

  const publish = () => {
    if (taskList.length > 0) {
      run(taskList.shift());
    }
  }

  const run = (params) => {
    const { fn, args } = params;

    switch (fn) {
      case 'lazyMan':
        lazyManFn.apply(null, args);
        break;
      case 'eat':
        eatFn.apply(null, args);
        break;
      case 'sleep':
        sleepFn.apply(null, args);
        break;
      case 'sleepFirst':
        sleepFirstFn.apply(null, args);
        break;
    }

  }

  const eat = fruit => {
    subscribe('eat', fruit);

    return ret;
  }

  const sleep = time => {
    subscribe('sleep', time);

    return ret;
  }

  const sleepFirst = time => {
    subscribe('sleepFirst', time);

    return ret;
  }

  const lazyManFn = name => {
    logFn("Hi!This is "+ name +"!");

    publish();
  }
  const eatFn = fruit => {
    logFn(`Eat ${fruit}.`);

    publish();
  }
  const sleepFn = time => {
    setTimeout(() => {
      logFn(`Wake up after ${time} seconds.`);
      publish();
    }, time * 1000);
  }
  const sleepFirstFn = time => {
    setTimeout(() => {
      logFn(`Wake up after ${time} seconds.`);
      publish();
    }, time * 1000);
  }

  const ret = {
    eat,
    sleep,
    sleepFirst,
    publish,
  }
  return ret;
}

function LazyMan(name) {
  const runner = LazyManRun(name, console.log);
  setTimeout(() => runner.publish(), 0);
  return runner;
}