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微笑着答应了,眼角却滑 ...
随机推荐
- Task 10 统计从1到某个整数之间出现的1的次数
任务:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求: 写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数.例如 f(12) = 5. 在3 ...
- ubuntu16.04+matlab r2015b VideoReader报错
读取.mp4出错 需要安装gstreamer0.10-ffmpeg ` sudo add-apt-repository ppa:mc3man/gstffmpeg-keep sudo apt-get u ...
- Fast Packet Processing - A Survey
笔记是边读边写的旁注,比较乱,没有整理就丢上来了. 可以说不仅要说fast packet process servey,也同时是一篇packet process的综述了.packet processi ...
- C++派生类构造函数调用顺序(详解)
我们来看下面一段代码: class B1 { public: B1(int i) {cout<<"constructing B1 "<<i<<e ...
- python selenium 代码
from selenium import webdriver from selenium.common.exceptions import TimeoutException, NoSuchElemen ...
- Linux内核0.11 bootsect文件说明
一.总体功能介绍 这是关于Linux-kernel-0.11中boot文件夹下bootsect.s源文件的说明,其中涉及到了一些基础知识可以参考这两篇文章. 操作系统启动过程 软盘相关知识和通过BIO ...
- Pytest - 进阶功能fixture
1. 概述 Pytest的fixture功能灵活好用,支持参数设置,便于进行多用例测试,简单便捷,颇有pythonic.如果要深入学习pytest,必学fixture. fixture函数的作用: 完 ...
- 理解 Delphi 的类(十一) - 深入类中的方法[8] - 抽象方法与抽象类
//抽象方法类似与接口; 在没有接口的年代 Delphi 是用抽象方法来模拟接口的; 我想它最终会被接口替代. {下面就定义了两个抽象方法} TMyClass = class(TObject) p ...
- 多进程编程之system()函数
1.system函数: 使用函数system,在程序中执行一个shell命令字符串很方便.它是一个和操作系统紧密相关的函数,用户可以使用它在自己的程序中调用系统提供的各种命令,执行系统的命令行,其实也 ...
- MyFlash闪回恢复数据
使用限制: .binlog格式必须为row,且binlog_row_image=full. .仅支持5.6与5.. .只能回滚DML(增.删.改). .mysqlbinlog版本请保持一致. 1.安装 ...