lazyMan実現


テーマは大体次のような機能を実現するプログラムです.
LazyMan(‘tom’)出力:“this is is tom”LazyMan(‘tom’).sleep(10).eat(‘apple’)出力:“this tom”待つ10秒…“at apple”LazyMan(‘tom’).eat(‘apple’).eat.eat.eat.eat.eat.eat(“babankatosasasasasasasasasasasasasasasasasasasant”ap.atois”ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.ap.“a(5)出力:5秒待ち…「this is tom」「eat bana」
分析
出力結果から見ていくつかの特徴があります.
  • チェーンの呼び出しは、ずっと呼び続けられます.一般的には、2つの方法で実施されます.キュー&promise.
  • ジョブは、出力順序と呼び出し位置が一致しているものと、sleepFirstであるものの2種類があります.コールは先に出力されます.したがって、ここでは、キューを採用して実装するのに適しています.タスクタイプによって、列の最後に追加されたものか、それともチームの先頭に追加されたものかを判断します.
  • は以上の分析に基づいて、関数を呼び出すたびにキューにタスクを追加するだけであることが分かりました.タスクは次のタイミングで実行されます.setTimeoutを使用して実装することが考えられます.
  • コードの実装
    class _LazyMan {
         
      constructor(name) {
         
        this.name = name;
        this.tasks = [this.sayName];  //         sayName    
        setTimeout(() => this.next(), 0)  //        ,           
      }
    
      /**
       *     
       * @param {function} task    
       * @param {boolean} addToTail      
       */
      addTask(task, addToTail = true) {
         
        if (addToTail) {
         
          this.tasks.push(task)
        } else {
         
          this.tasks.unshift(task)
        }
      }
    
      //               
      next = () => {
         
        const task = this.tasks.shift()
        task && task()
      }
    
      sayName = () => {
         
        console.log(`this is ${
           this.name}`)
        this.next()
      }
      eat = (name) => {
         
        this.addTask(() => {
         
          console.log(`eat ${
           name}`)
          this.next()
        })
        return this     //   return this       ,         
      }
    
      sleep = (time) => {
         
        this.addTask(this.sleepTask(time))
        return this
      }
    
      sleepFirst = (time) => {
         
        this.addTask(this.sleepTask(time), false)
        return this
      }
    
      sleepTask = (time) => {
         
        return () => {
         
          console.log(`  ${
           time}  ...`)
          setTimeout((() => {
         
            this.next()
          }), time * 1000)
        }
      }
    }
    
    function LazyMan(name) {
         
      return new _LazyMan(name)
    }
    
    詳細はこちらをクリックしてください.
    参考文献:
    lazyMan