一步一步实现基于Task的Promise库(三)waitFor方法的设计
在上一篇中我们已经完成了Task.js里面的all和any方法,已经可以完美的解决大部分需求,我们再来看一个需求:
我们要先读取aa.txt的内容,然后去后台解析,同时由用户指定一个文件,也要读取解析,然后当两个文件都解析完了,我们还要合并两部分内容存到cc.txt中,最后发个通知说ok了。。
这里的用户是指真正浏览网页的用户,可能是说让用户上传一个文件去读取解析,但是aa.txt是程序定好了的,我们也不希望用户上传文件之后再去读取解析aa.txt,怎么办?如果有一个waitFor方法可以等待另一个任务的完成就好了,请看下面代码:
var taskExp_1 = new Task(readFile, "aa.txt").then(resolveFile, "/service/fileResolve.ashx?file=aa.txt");
var taskExp_2 = new Task(uploadFile, "bb.txt").then(readFile, "bb.txt").then(resolveFile, "/service/fileResolve.ashx?file=bb.txt");
var taskExp_3 = new Task(taskExp_1).waitFor(taskExp_2).then(writeFile, ["cc.txt"]).then(sendMail).start();
$("#btnUpload").click(function (){
taskExp_2.start();
});
上面代码中的waitFor方法并不会导致taskExp_2的执行,如果用户不点击btnUpload按钮来触发taskExp_2.start(); 那么taskExp_3将一直等待taskExp_2的执行并完成,然后才能进行后面的writeFile。嗯,这样确实可以解决这个头疼的需求,下面我们来看看waitFor方法该如何设计呢?
先看看下面两句代码有什么区别?
var taskExp3_2 = new Task(readFile, "bb.txt").waitFor(taskExp3_1).then(mergeContent).start();
var taskExp3_2 = new Task([readFile, "bb.txt"], taskExp3_1).all(mergeContent).start();
区别在于使用all方法会导致taskExp3_1的执行,而waitFor不会,如果没有taskExp3_1.start()这句话,taskExp3_2永远也不可能执行完成,它会一直等待taskExp3_1的执行并完成,除此之外就没有区别了.那么waitFor方法的定位就是设计给那些不希望即时执行的Task的(如果你希望Task的即时执行,那么请用all)
从逻辑上来说上面的taskExp3_1是不需要接收readFile的返回参数的,那么readFile的返回参数实际上是给后面的mergeContent使用的.我们实际上是把
new Task(readFile, "bb.txt").waitFor(taskExp3_1).then(mergeContent).start();
转换成
new Task([readFile, "bb.txt"], taskExp3_1).all(mergeContent).start();
只不过我们不让taskExp3_1触发执行. 然后我们还希望mergeContent回调方法里面可以通过this.Param[0]和this.Param[1]分别取到readFile和taskExp3_1的输出参数.
那么waitFor方法最复杂的情况是什么呢?
var taskExp3_2 = new Task([func1],[func2],[func3]).waitFor(task1, task2).then(callback).start();
只有在func1,func2,func3,task1,task2都执行完成了才会执行callback,并且task1,task2必须自己调用start()触发执行,否则taskExp3_2会一直等待.
其实我们已经发现有点不对劲了,那就是waitFor方法为什么一定要耦合func1,func2,func3的all逻辑呢?
var taskExp3_2 = new Task([func1],[func2],[func3]).all().waitFor(task1, task2).then(lastFunc).start();
这样做是不是更好呢? 答案是肯定的,我们应该设计all(),any(),new Task(),好处是支持了下面几种写法:
//写法一
var taskExp3_2 = new Task([func1],[func2],[func3]).any().waitFor(task1, task2).then(lastFunc).start();
//写法二
var taskExp3_2 = new Task().waitFor(task1, task2).then(lastFunc).start();
//写法三
var task1 = new Task(func1).then([func2],[func3]).all(); //如果没有这个all(),task1的完成就有歧义,是func2,func3都完成才叫完成还是一个完成就叫完成?
var task2 = new Task(task1).then(lastFunc).start();
看来在实现waitFor方法之前我们要先实现all(),any(),new Task()这些不传参的方法,同时这些方法的实现要注意什么呢?
var taskExp3_2 = new Task([func1],[func2]).all().then(callback1);
这句代码应该等效于:
var taskExp3_2 = new Task([func1],[func2]).all(callback1);
同时func1,func2返回的参数不能因为all()的执行而传递不到callback1。在下一章我们来实现这些不传参的方法。
一步一步实现基于Task的Promise库(三)waitFor方法的设计的更多相关文章
- 一步一步实现基于Task的Promise库(五)waitFor和waitForAny的实现
在实现waitFor方法之前,我们先要搞明白下面这些问题: 1. waitFor方法的形参有限制吗? 没有!如果形参是Task类型,不应该启动Task,如果是function类型,会执行方法.所以wa ...
- 一步一步实现基于Task的Promise库(四)无参数的WorkItem
接着上一篇我直接给出代码,现在支持了new Task(), then(), all(), any() 这些不传参的调用方式. (function(){ var isFunction = functio ...
- 一步一步实现基于Task的Promise库(二)all和any方法的设计和实现
在上一篇中我们已经初步完成了Task类,如果仅仅是这些,那么没有多大意义,因为网上这类js库有很多,现在我们来些更复杂的使用场景. 如果我们现在有这样一个需求:我们要先读取aa.txt的内容,然后去后 ...
- 一步一步实现基于Task的Promise库(一)Promise的基本实现
如果我们现在有一个需求,大概是先读取一个文件的内容,再把得到的内容传给后台去解析,最后把解析后的结果再保存到那个文件,按照最原始的做法代码就是下面这个样子的: //读取文件的原始内容 var read ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理
状态管理和上一章的订阅发布都算是Dapr相较于其他服务网格框架来讲提供的比较特异性的内容,今天我们来讲讲状态管理. 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务
我个人认为Actor应该是Dapr里比较重头的部分也是Dapr一直在讲的所谓"stateful applications"真正具体的一个实现(个人认为),上一章讲到有状态服务可能很 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流
在一般的互联网应用中限流是一个比较常见的场景,也有很多常见的方式可以实现对应用的限流比如通过令牌桶通过滑动窗口等等方式都可以实现,也可以在整个请求流程中进行限流比如客户端限流就是在客户端通过随机数直接 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权
Oauth2授权,熟悉微信开发的同学对这个东西应该不陌生吧.当我们的应用系统需要集成第三方授权时一般都会做oauth集成,今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定
如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...
随机推荐
- 比ORA-24777: 我不使用不可移植数据库链接更郁闷的事情达成一致
现场有一个同步误差,内容如下面: java.sql.BatchUpdateException: ORA-24777: 不同意使用不可移植的数据库链路 at oracle.jdbc.driv ...
- Java中间(三十五)-----Java详细设置(一个):请指定初始容量设置
集合是我们在Java编程中使用很广泛的,它就像大海,海纳百川,像万能容器,盛装万物.并且这个大海,万能容器还能够无限变大(假设条件同意). 当这个海.容器的量变得很大的时候,它的初始容量就会显得很重要 ...
- 下载文档--Struts2中国的文件下载被显示为空间的问题
下载文档--Struts2中国人似乎是空文件下载格问题 前言:近期公司项目中用到文件下载,依据底层,决定使用struts2的文件下载模式. 乱码大多数都攻克了,竟然出现中文文件下载时,中文文字显示为空 ...
- asp.net学习之数据绑定控件、数据源控件概述
原文:asp.net学习之数据绑定控件.数据源控件概述 1.asp.net数据绑定控件分为三大类,每个类分别进行详细: ● 列表式数据绑定控件: 列表式数据绑定控件常用来在一个表格内的一个字 ...
- CSS定位:几种类型的position定位的元素
当人们刚接触布局的时候都比较倾向于使用定位的方式.因为定位的概念看起来好像比较容易掌握.表面上你确切地指定了一个块元素所处的位置那么它就会坐落于那里.可是定位比你刚看到的时候要稍微复杂一点.对于定位来 ...
- 兼容Firefox和IE的onpropertychange事件oninput
原文 兼容Firefox和IE的onpropertychange事件oninput onpropertychange能够捕获每次输入值的变化.例如:对象的value值被改变时,onpropertych ...
- 一起学习android使用一个回调函数onCreateDialog实现负载对话(23)
效果图: 有时候我们须要去做一个Activity启动时的数据载入对话框,关于对话框的各种实现能够通过一起学android之对话框 Dialog的创建(7)来完毕,在这里另外介绍一个,利用onCreat ...
- Java 实现装饰(Decorator)模式
在Java在.io反映非常多类包下是典型的装饰格局,例如: new BufferedOutputStream(OutputStream out) new BufferedInputStream(Inp ...
- EF4.1: Add/Attach and Entity States(EF中的实体状态转换说明)
实体的状态,连接以及 SaveChanges 方法 数据库上下文对象维护内存中的对象与数据库中数据行之间的同步.这些信息在调用 SaveChanges方法被调用的时候使用.例如,当使用 Add 方法传 ...
- 软件开发V型号
RAD(rap application development),就是软件开发过程中的一个重要模型,称为高速应用开发模型.其模型构图形似字母V,所以又称V模型. 他通过开发和測试同一时候进行 ...