LazyMay:实现同步和异步任务的顺序执行
在掘金看到的文章,流程控制同步和异步任务的顺序执行,收益匪浅,工作中能用到。
1、实现以下效果
实现一个LazyMan,可以按照以下方式调用:
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”).sleepFirst(5).eat(“supper”)输出
//等待5秒
Wake up after 5
Hi This is Hank!
Eat supper 以此类推。
这是典型的JavaScript流程控制,问题的关键是如何实现任务的顺序执行。在Express有一个类似的东西叫中间件,这个中间件和我们这里的吃饭、睡觉等任务很类似,每一个中间件执行完成后会调用next()函数,这个函数用来调用下一个中间件。
对于这个问题,我们也可以利用相似的思路来解决,首先创建一个任务队列,然后利用next()函数来控制任务的顺序执行:
1.2 队列方式实现
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!");
},time*1000);
}
})(time);
this.tasks.unshift(fn);
return this;
}
/* 封装 */
function LazyMan(name){
return new _LazyMan(name);
}
1.3 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;
})
})
},
sleepFirst: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');
},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~~
LazyMay:实现同步和异步任务的顺序执行的更多相关文章
- js同步、异步、回调的执行顺序以及闭包的理解
首先,记住同步第一.异步第二.回调最末的口诀 公式表达:同步=>异步=>回调 看一道经典的面试题: for (var i = 0; i < 5; i++) { setTimeout( ...
- silverlight——多次异步调用的顺序执行
遇到这样一个功能需求,对于后台的同一个服务调用多次,但要求传入的参数能够再一个执行完之后再进行另一个参数的执行. 由于silverlight支持的是异步调用机制,故无法控制服务调用何时返回.那么如果使 ...
- ajax同步处理(使得JS按顺序执行)
在项目中碰到一个问题: 图一: 图二: 函数1代码:这里是因为有ajax请求,默认的是异步的 //点击分页页码,请求后台返回对应页码的数据 function getdata(fewPage,flag, ...
- 更优雅的方式: JavaScript 中顺序执行异步函数
火于异步 1995年,当时最流行的浏览器--网景中开始运行 JavaScript (最初称为 LiveScript). 1996年,微软发布了 JScript 兼容 JavaScript.随着网景.微 ...
- js eventLoop (使用chunk 同步变异步)
https://www.cnblogs.com/xiaohuochai/p/8527618.html 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与 ...
- JS中同步和异步
首先,我们要知道,JavaScript的本质是一门浏览器脚本语言,在执行的时候是一行一行的执行,只有前面的代码执行完了才会执行后面的代码.JS是单线程语言指的就是这个意思. 同步和异步其实在进行任务执 ...
- 7-ajax的同步和异步?
同步和异步统一根据send()执行的位置来实现分割逻辑同步:1.send()后统一不会被执行,直到http事务完成之后才会之后后续逻辑.2.堵塞send()方法的逻辑.异步:1.send()后面照样执 ...
- ES6 Promise 让异步函数顺序执行
应用 ES6 的 内置对象 Promise, 让异步函数 按顺序执行的例子 如下: 上边 是四个用Promise 处理过的 异步执行的函数: fn1.fn2.fn3.fn4 下面,让其按顺序执行 如下 ...
- 「JavaScript」同步、异步、回调执行顺序之经典闭包setTimeout分析
聊聊同步.异步和回调 同步,异步,回调,我们傻傻分不清楚, 有一天,你找到公司刚来的程序员小T,跟他说:“我们要加个需求,你放下手里的事情优先支持,我会一直等你做完再离开”.小T微笑着答应了,眼角却滑 ...
随机推荐
- 《 Spring1之第二次站立会议(重发)》
< 第二次站立会议(重发)> 昨天,我把找到的代码和协议资料等相关资料在团队里做了相应的汇报: 今天,我对自己找到的代码进行了相关的了解后,把它们在编译环境中进行了编译以及接着对代码进行逐 ...
- 《Spring1之 第一次站立会议(重发)》
< 第一次站立会议(重发)> 昨天,我对我们团队要做的项目进行了相关资料的查找,我找到了服务器和客户端的相关代码以及找到了把它们通信所使用TCP/IP等协议: 今天,我把找到的代码和协议资 ...
- angularJS1笔记-(19)-angular异步加载包的方式
我们平时写的导入包的方式都是同步方式,有时候会显得过于卡顿,这样我们就可以使用异步加载的方式. script.js方式: 执行结果为: 异步加载还可以加载多个即为script([,,,],functi ...
- jsp与Ajax技术
Ajax 是Asynchronous Javascript and XML的缩写,异步的JavaScript和xml.Ajax是由JavaScript.XML.CSS.DOM等多种已有技术的结合,它可 ...
- 结队第二次作业——WordCount进阶需求
结队第二次作业--WordCount进阶需求 博客地址 051601135 岳冠宇 博客地址 051604103 陈思孝 博客地址 Github地址 具体分工 队友实现了爬虫功能,我实现了wordco ...
- lr基本的概念
并发用户数量:与服务器进行交互的在线用户数量 请求响应时间:从client端发出请求到得到响应的整个时间,它一般包括网络相应时间+server的响应时间 事务请求响应时间:完成这个事务所用的时 ...
- 如何实现MySQL表数据随机读取?从mysql表中读取随机数据
文章转自 http://blog.efbase.org/2006/10/16/244/如何实现MySQL表数据随机读取?从mysql表中读取随机数据?以前在群里讨论过这个问题,比较的有意思.mysql ...
- PHP 常用函数总结(一)
重点: 看函数的 ‘参数’ 和 ‘返回值’ 文档:http://www.w3school.com.cn/php/php_ref_array.asp http://www.w3school.com.cn ...
- SpringBoot(十三)_springboot上传Excel并读取excel中的数据
今天工作中,发现同事在整理数据,通过excel上传到数据库.所以现在写了篇利用springboot读取excel中的数据的demo.至于数据的进一步处理,大家肯定有不同的应用场景,自行修改 pom文件 ...
- LINQ to SQL和Entity Framework
LINQ to SQL和Entity Framework都是一种包含LINQ功能的对象关系映射技术. 那么为什么会有LINQ这个东西的出现呢. 简单来说LINQ是为了满足不知道怎么操作数据库的程序员开 ...