js es6 class实现LazyMan.你可以学到,链式调用、同步异步。

实现一个LazyMan你可以学到,链式调用、class、同步异步、Promise、回调函数、箭头函数。

可以按照以下方式调用:

/**
    LazyMan(“Hank”)输出:
    Hi! This is Hank!

    LazyMan(“Hank”).sleep(10).eat(“dinner”)输出
    Hi! This is Hank!
    //等待10秒..
    Wake up after 10
    Eat dinner~

    LazyMan(“Hank”).eat(“dinner”).eat(“supper”)输出
    Hi This is Hank!
    Eat dinner~
    Eat supper~

    LazyMan(“Hank”).eat(“supper”).sleepFirst(5)输出
    //等待5秒
    Wake up after 5
    Hi This is Hank!
    Eat supper
 */

主要的实现思路是,第一步先class 一个对象,在construstor 函数初始化一个callBacks 数组,再去class里写入对应的方法,方法里面写入需要的延迟函数,或者是不需要延迟的函数。每当链式调用把this返回出去this就是当前的class方便下次在进行调用,把每一个延迟函数放到callBacks数组当中。然后在去循环callBacks数组,以同步的方式进行调用这样不管你的函数延迟多少秒,当延迟函数不走完下一个函数是不会进行的。这就是大概的实现思路。

1.定义class 写一个callbacks 数组

class _LazyMan {
  constructor(name) {
    this.callbacks = []
  }
}

2.将callbacks数组同步进行执行,循环同步执行代码。

class _LazyMan {
  constructor(name) {
    this.callbacks = []
    // 循环同步执行代码
    setTimeout(async () => {
      for (let i = 0; i < this.callbacks.length; i++) {
        const fn = this.callbacks[i]
        await fn()
      }
    })
  }
}

3.输出方法开始 LazyMan('Hank') // Hi This is Hank!

class _LazyMan {
  constructor(name) {
    this.callbacks = []
    // 第一次实例hua调用函数执行
    const task = () => {
      this.say(name)
    }
    this.callbacks.push(task) // 初始化放一个函数

    setTimeout(async () => { // 循环同步执行 延迟函数不走完下一个函数是不会走的。
      for (let i = 0; i < this.callbacks.length; i++) {
        const fn = this.callbacks[i]
        await fn()
      }
    })
  }
  say (name) {
    console.log(` Hi This is ${name}!`)
    return this
  }
}
function LazyMan (name) {
  return new _LazyMan(name)
}
LazyMan('Hank') //  Hi This is Hank!

为什么不用forEach循环进行async呢?因为forEach不支持这样操作,原因callback 其实是我们传入的一个被 async 封装的 promise 对象,而 Array.prototype.forEach 内部并未对这个promise 对象做任何处理,foreach的实现并没有return 返回值,只是忽略它。可以去github看看forEach的源码。forEach 只支持同步,不支持异步。

4.输出方法开始 LazyMan(“Hank”).sleep(10).eat(“dinner”)输出

class _LazyMan {
  constructor(name) {
    this.callbacks = []
    const task = () => {
      this.say(name)
    }
    this.callbacks.push(task)
    setTimeout(async () => {
      for (let i = 0; i < this.callbacks.length; i++) {
        const fn = this.callbacks[i]
        await fn()
      }
    })
  }
  say (name) {
    console.log(` Hi This is ${name}!`)
    return this
  }
  eat (food) {
    const task = () => {
      console.log(`Eat ${food}~`)
    }
    this.callbacks.push(task)
    return this
  }
  // 阻塞time * 1000秒后在执行下面的任务
  sleep (time) {
    const task = () => {
      // 返回一个新的 promise 对象
      return new Promise((resolve) => {
        setTimeout(resolve, time * 1000)
      })
        .then(() => {
          console.log(`Wake up after ${time}`)
        })
    }
   //  callbacks 放入延迟执行函数
    this.callbacks.push(task)
    //重新返回 _LazyMan 为了后续继续链式调用
    return this
  }
}
function LazyMan (name) {
  return new _LazyMan(name) // 实例化_LazyMan方法
}


LazyMan('Hank').sleep(10).eat('dinner')// Hi This is Hank!  Wake up after 10   Eat dinner~
LazyMan('Hank').eat('dinner').eat('supper') //  Hi This is Hank!  Eat dinner~  Eat supper~ 

5.输出方法开始LazyMan(“Hank”).eat(“supper”).sleepFirst(5)输出

完整版本

class _LazyMan {
  constructor(name) {
    this.callbacks = []
    const task = () => {
      this.say(name)
    }
    this.callbacks.push(task)
    setTimeout(async () => {
      for (let i = 0; i < this.callbacks.length; i++) {
        const fn = this.callbacks[i]
        await fn()
      }
    })
  }
  say (name) {
    console.log(` Hi This is ${name}!`)
    return this
  }
  eat (food) {
    const task = () => {
      console.log(`Eat ${food}~`)
    }
    this.callbacks.push(task)
    return this
  }
  // 阻塞time * 1000秒后在执行下面的任务
  sleep (time) {
    const task = () => {
      return new Promise((resolve) => {
        setTimeout(resolve, time * 1000)
      })
        .then(() => {
          console.log(`Wake up after ${time}`)
        })
    }
    this.callbacks.push(task)
    return this
  }
  // 先阻塞time * 1000秒后在依次执行任务
  sleepFirst (time) {
    const task = () => {
      return new Promise((resolve) => {
        setTimeout(resolve, time * 1000)
      })
        .then(() => {
          console.log(`Wake up after ${time}`)
        })
    }
    this.callbacks.unshift(task) //只要调用sleepFirst就把函数放到第一个执行
    return this
  }
}
function LazyMan (name) {
  return new _LazyMan(name)
}

// LazyMan('Hank')
// LazyMan('Hank').sleep(10).eat('dinner')
// LazyMan('Hank').eat('dinner').eat('supper')
LazyMan('Hank').eat('supper').sleepFirst(5)

我是阿豪

猜你喜欢

转载自blog.csdn.net/qq_54753561/article/details/128648897