Promise实现的lazyman.

首先请看网友通过setTimeout实现的:

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模拟线程,有一个事件处理队列(this.tasks,然后每一个事件内部会调用事件调度函数(next),每一次的业务逻辑是通过定义的闭包函数fn,fn内部在处理完自身业务会执行next函数。

于是就想起处理这种含有异步并且有一定阻塞的业务,promise是非常合适的,实现思路是完全不同的

首先得思考:

  lazyman里边含有链式调用,那么每一个子任务 return this;这个程序支持任务优先顺序,那么就需要两个贯穿全场的Promise对象:第一,普通顺序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(something) { this.order(function(resolve) { console.log(something + '~~') 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~~

 

注意每一个任务的业务逻辑都是通过回调函数的形式实现的,内部拥有两种API:

  1 this.order(function(){ ... })

  2 this.insert(function() {... })

这里的核心需要注意以下几点:

  1 每一次任务的业务逻辑函数,就是这个回调函数传给对应的API,执行场地在它那。

  2 每一个API的执行权利交给任务函数自身,是通过参数传递的方式,例如: fn(resolve),每一个任务函数在执行完自身业务逻辑后,通过resolve()改变Promise对象状态为Resolved(其他:rejected pending).

  3 连个API的优先级实现,通过一个this.fir的状态值来判断是否含有插入promise对象,如果有就,就做一件事情改变fn发生的时间: insertPromise.then(function(){ fn(resolve) })

 

通过上边的实现,最后总结一下,在设计程序的时候,首先想想程序的大概构成,然后在开始写,这样大思路不会跑,进而很快就写出来了。

posted on 2017-02-04 10:47  firegood 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/firegood/p/6364243.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值