实用题:LazyMan

实现

function LazyMan(name: string) {
  console.log('Hi,This is ' + name);
  let queue = Promise.resolve();

  function then(cb: (done: Function) => void) {
    const q = queue;
    queue = new Promise((res) => {
      q.then(() => {
        cb(res);
      });
    });
  }

  const obj = {
    sleep(seconds: number) {
      then((done) => {
        setTimeout(() => {
          console.log('Wake up after', seconds);
          done();
        }, seconds * 1000);
      });

      return obj;
    },
    eat(foodType: string) {
      then((done) => {
        console.log('Eat ' + foodType);
        done();
      });
      return obj;
    },
  };

  return obj;
}

实用性

这个函数还是很有用的,稍微改变一下就能在业务中使用。

比如说要实现这样一个业务:先等待10秒做某事,然后再等待10秒做其他事
那么我们可能会这样写

setTimeout(() => {
  console.log("do something");
  setTimeout(() => {
     console.log("do something else");
  }, 10 * 1000);
}, 10 * 1000)

然后再扩展时可能就得在内部再添加setTimeout,然后无限嵌套下去成为回调地狱

调整

export function lazy() {
    let queue = Promise.resolve();

    function then(cb: (done: Function) => void) {
        const q = queue;
        queue = new Promise((res) => {
            q.then(() => cb(res));
        });
    }

    const obj = {
        /**
         * @param {number} ms 等待毫秒数
         */
        wait(ms: number) {
            then((done) => setTimeout(done, ms));
            return obj;
        },

        /**
         * @param {((done: Function) => void) | (() => Promise<any>)} cb 回调返回空或返回一个promise
         */
        do(cb: ((done: Function) => void) | (() => Promise<void>)) {
            then((done) => {
                const res = cb(done);
                if (res) {
                    res.then(() => done());
                }
            });
            return obj;
        },
    };

    return obj;
}

使用

lazy()
  .wait(10 * 1000)
  .do((done) => {
    console.log("do something");
    done();
  })
  .wait(10 * 1000)
  .do((done) => {
    console.log('do something else');
    done();
  });

这样就清晰很多了,令代码更容易阅读

另一种解决方法

export function sleep(ms: number): Promise<void> {
    return new Promise(res => setTimeout(res, ms));
}
(async function(){
   await sleep(10 * 1000);
   console.log("do something");
   await sleep(10 * 1000);
   console.log("do something else");
})();

评论

0 / 800
全部评论()