firegood

Web前端

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

手机发布,空格都是一个个敲出来的,请网友见谅,以后会改进
先看网上版本:

function _LazyMan(name) {
    this.tasks = [];
    var self = this;
    var fn = (function(n) {
        var name = n;
        return function() {
             console.log("Hi! This is " + name + "!");
             self.next();
        }
    })(name);
    this.tasks.push(fn);
    setTimeout(function() {
    self.next();
},
0); // 在下一个事件循环启动任务
}
/* 事件调度函数 */
_LazyMan.prototype.next = function() {
    var fn = this.tasks.shift();
    fn && fn();
}
_LazyMan.prototype.eat = function(name) {
    var self = this;
    var fn = (function(name) {
        return function() {
            console.log("Eat " + name + "~");
            self.next()
        }
    })(name);
    this.tasks.push(fn);
    return this; // 实现链式调用
}
_LazyMan.prototype.sleep = function(time) {
    var self = this;
    var fn = (function(time) {
        return function() {
            setTimeout(function() {
                console.log("Wake up after " + time + "s!");
                self.next();
            },time * 1000);
        }
    })(time);
    this.tasks.push(fn);
    return this;
}
_LazyMan.prototype.sleepFirst = function(time) {
    var self = this;
    var fn = (function(time) {
         return function() {
             setTimeout(function() {
                  console.log("Wake up after " + time + "s!");
                  self.next();
              },time * 1000);
          }
    })(time);
    this.tasks.unshift(fn);
    return this;
}
/* 封装 */
function LazyMan(name) {
     return new _LazyMan(name);
}
LazyMan('Hank').sleepFirst(5).sleep(10).eat('dinner')

 

 

以上原理:用setTimeout模拟线程,有一个事件处理队列,然后每一个事件内部会调用事件调度函数。

写的也是非常巧妙,想了一下,这种异步处理,promise是最擅长干这个的,于是自己用Promise试着实现了一个:

 


function _lazyman(name) {
    this.orderPromise = this.newPromise(); //定义顺序promise对象
    this.insertPromise = this.newPromise(); //定义插入promise对象
    this.order(function(resolve) {
        console.log(name);
        resolve();
    })
}
_lazyman.prototype = {
/*实例化promise对象工厂
*/
    newPromise: function() {
        return new Promise(function(resolve, reject) {
            resolve();
        })
    },
    order: function(fn) {
          var self = this;
          this.orderPromise = this.orderPromise.then(function() {
               return new Promise(function(resolve, reject) {
              //如果有insertPromise,阻塞orderPromise.
                      self.fir ? self.insertPromise.then(function() {
                            fn(resolve)
                      }) : fn(resolve);
                })
          })
     },
     insert: function(fn) {
           var self = this;
           this.fir = true;
           this.insertPromise = this.insertPromise.then(function() {
                 return new Promise(function(resolve, reject) {
                         fn(resolve) self.fir = false;
                 })
           })
     },
      firstTime: function(time) {
            this.insert(function(resolve) {
                  setTimeout(function() {
                         console.log('wait ' + time + ' s, other logic');
                         resolve();
                  },time * 1000)
            }) return this;
       },
      eat: function(fan) {
             this.order(function(resolve) {
                     console.log(fan + '~~') resolve();
             })

            return this;
      },
     sleep: function(time) {
           this.order(function(resolve) {
                  setTimeout(function() {
                          console.log('sleep ' + time + ' s');
                          resolve()
                  },time * 1000);
          })         

           return this;

      }
}
//接口封装。
function lazyman(name) {
      return new _lazyman(name);
}
//调用测试
lazyman('RoryWu').firstTime(1).sleep(2).firstTime(3).eat('dinner').eat('breakfast');
// 弹出:
// wait 1 s, other logic
// wait 3 s, other logic
// RoryWu
// sleep 2 s
// dinner~~
// breakfast~~

posted on 2017-01-20 15:23  firegood  阅读(62)  评论(0)    收藏  举报