liuzeyafzy / brand-new

MIT License
1 stars 1 forks source link

要求设计 LazyMan 类,实现以下功能 #5

Open sunbigshan opened 5 years ago

sunbigshan commented 5 years ago
LazyMan('Tony');
// Hi I am Tony

LazyMan('Tony').sleep(10).eat('lunch');
// Hi I am Tony
// 等待了10秒...
// I am eating lunch

LazyMan('Tony').eat('lunch').sleep(10).eat('dinner');
// Hi I am Tony
// I am eating lunch
// 等待了10秒...
// I am eating diner

LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
// Hi I am Tony
// 等待了5秒...
// I am eating lunch
// I am eating dinner
// 等待了10秒...
// I am eating junk food
jiangjiang01 commented 5 years ago

done


function sleep(time) {
    return new Promise((reslove) => {
        setTimeout(reslove, time);
    });
}

function LazyMan(name) {
    if (!new.target) {
        return new LazyMan(name);
    }
    this.name = name;
    const execFn = [];

    console.log(`Hi I am ${this.name}`);

    let addPipeTimer = null;

    this._push = function(fn, time = 0) {
        execFn.push({
            fn,
            time
        });
        this._execAll();
    };

    this._unshift = function(fn, time = 0) {
        execFn.unshift({
            fn,
            time
        });
        this._execAll();
    };

    this._execAll = function() {
        clearTimeout(addPipeTimer);
        addPipeTimer = setTimeout(async () => {
            if (!execFn.length) {
                return;
            }
            while(execFn.length > 0) {
                const obj = execFn.shift();
                if (obj.time) {
                    await sleep(obj.time);
                }
                obj.fn();
            }
        }, 0);
    }

    this.eat = function(meal) {
        this._push(() => {
           console.log(`I am eating ${meal}`);
        });
        return this;
    };

    this.sleep = function(time) {
        this._push(() => {
           console.log(`等待了${time}秒...`);
        }, time * 1000);
        return this;
    };

    this.sleepFirst = function(time) {
        this._unshift(() => {
            console.log(`等待了${time}秒...`);
        }, time * 1000);
        return this;
    };

    return this;
}

参考大善的class写法


function sleep(time) {
    return new Promise((reslove) => {
        setTimeout(reslove, time);
    });
}

function LazyMan(name) {
    return new LazyManFactory(name);
}

class LazyManFactory {
    constructor(name) {
        this.timer = null;
        this.name = name;
        this.tasks = [];
    }
    eat(meal) {
        this.tasks.push({
           fn: () => {
               console.log(`I am eating ${meal}`);
           }
        });
        this.exec();
        return this;
    }
    _sleep(index, time) {
        this.tasks.splice(index, 0, {
           fn: () => {
               console.log(`等待了${time}秒...`);
           },
           time: time
        });

        this.exec();
        return this;
    }
    sleep(time) {
        return this._sleep(this.tasks.length, time);
    }
    sleepFirst(time) {
        return this._sleep(0, time);
    }
    exec() {
        clearTimeout(this.timer);
        this.timer = setTimeout(async () => {
            console.log(`Hi I am ${this.name}`);
            const tasks = this.tasks;
            const len = tasks.length;
            let index = 0;
            while(index < len) {
                const task = tasks[index];
                if (task.time) {
                    await sleep(task.time * 1000);
                }
                task.fn();
                index ++;
            }
        }, 0);
    }
}

Test


// Test
function test1() {

    LazyMan('Tony');
}

function test2() {
    LazyMan('Tony').sleep(2).eat('lunch');
}

function test3() {
    LazyMan('Tony').eat('lunch').sleep(2).eat('dinner');
}

function test4() {
    (new LazyMan('Tony')).eat('lunch').eat('dinner').sleepFirst(1).sleep(2).eat('junk food');
}

async function test() {
//     await test1();
//     await test2();
//     await test3();
    await test4();
}

test();
// Hi I am Tony
// 等待了1秒...
// I am eating lunch
// I am eating dinner
// 等待了2秒...
// I am eating junk food
sunbigshan commented 5 years ago

第一步:初始化

function LazyMan (name) {
  return new LazyManFactory(name);
}

class LazyManFactory {
  constructor (name) {
    console.log(`Hi I am ${name}`)
  }
}

LazyMan('Tony');
// Hi I am Tony

第二步:实现 eat 方法

function LazyMan (name) {
  return new LazyManFactory(name);
}

class LazyManFactory {
  constructor (name) {
    console.log(`Hi I am ${name}`)
  }
  eat (food) {
    console.log(`I am eating ${food}`)
  }
}

LazyMan('Tony').eat('lunch');
// Hi I am Tony
// example.js:10 I am eating lunch

第三步:实现 sleep 方法

function LazyMan (name) {
  return new LazyManFactory(name);
}

class LazyManFactory {
  constructor (name) {
    console.log(`Hi I am ${name}`)
    this.tasks = [];
    setTimeout(() => {
      this.next()
    }, 0)
  }
  eat (food) {
    const fn = () => {
      console.log(`I am eating ${food}`)
      this.next();
    }
    this.tasks.push(fn)
    return this;
  }
  sleep (wait) {
    const fn = () => {
      setTimeout(() => {
        console.log(`等待了${wait}秒...`)
        this.next();
      }, wait * 1000)
    }
    this.tasks.push(fn)
    return this;
  }
  next () {
    const fn = this.tasks.shift();
    fn && fn();
  }
}

LazyMan('Tony').eat('lunch').sleep(10).eat('dinner');
// Hi I am Tony
// I am eating lunch
// 等待了10秒...
// I am eating diner

第四步:实现 sleepFirst 方法

我就不用多说了吧~~~