上一篇中我们已经完成了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方法的设计的更多相关文章

  1. 一步一步实现基于Task的Promise库(五)waitFor和waitForAny的实现

    在实现waitFor方法之前,我们先要搞明白下面这些问题: 1. waitFor方法的形参有限制吗? 没有!如果形参是Task类型,不应该启动Task,如果是function类型,会执行方法.所以wa ...

  2. 一步一步实现基于Task的Promise库(四)无参数的WorkItem

    接着上一篇我直接给出代码,现在支持了new Task(), then(), all(), any() 这些不传参的调用方式. (function(){ var isFunction = functio ...

  3. 一步一步实现基于Task的Promise库(二)all和any方法的设计和实现

    在上一篇中我们已经初步完成了Task类,如果仅仅是这些,那么没有多大意义,因为网上这类js库有很多,现在我们来些更复杂的使用场景. 如果我们现在有这样一个需求:我们要先读取aa.txt的内容,然后去后 ...

  4. 一步一步实现基于Task的Promise库(一)Promise的基本实现

    如果我们现在有一个需求,大概是先读取一个文件的内容,再把得到的内容传给后台去解析,最后把解析后的结果再保存到那个文件,按照最原始的做法代码就是下面这个样子的: //读取文件的原始内容 var read ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理

    状态管理和上一章的订阅发布都算是Dapr相较于其他服务网格框架来讲提供的比较特异性的内容,今天我们来讲讲状态管理. 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务

    我个人认为Actor应该是Dapr里比较重头的部分也是Dapr一直在讲的所谓"stateful applications"真正具体的一个实现(个人认为),上一章讲到有状态服务可能很 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流

    在一般的互联网应用中限流是一个比较常见的场景,也有很多常见的方式可以实现对应用的限流比如通过令牌桶通过滑动窗口等等方式都可以实现,也可以在整个请求流程中进行限流比如客户端限流就是在客户端通过随机数直接 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权

    Oauth2授权,熟悉微信开发的同学对这个东西应该不陌生吧.当我们的应用系统需要集成第三方授权时一般都会做oauth集成,今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

随机推荐

  1. 【翻译】在Ext JS 5应用程序中怎样使用路由

    原文:How to Use Routing in Your Ext JS 5 Apps 简单介绍 Ext JS 5是一个重要的公布版本号,它提供了很多新特性来创建丰富的.企业级的Web应用程序.MVV ...

  2. SQLServer-----SQLServer 2008 R2卸载

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVrZXdhbmd6aQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  3. JTextField限制输入长度的完美解决方案(转)

    关于JTextField限制输入字符长度的问题,因为没提供现成的api,所以我们得自己动手,来实现这个功能,网上也有很多这样的资料,大多是在JTextField的Document的insertStri ...

  4. 添加AD验证(域身份验证)到现有网站

    每个网站几乎都会有用户登录的模块,登录就会涉及到身份验证的过程.通常的做法是在页面上有个登录的Form,然后根据用户名和密码到数据库中去进行验证. 而验证后如何在网站的各个页面维持这种认证过的状态,有 ...

  5. 如何解决KEIL 5 编KEIL4同RTX系统的project解

    1.我个人KEIL5与KEIL4对照 相较于KEIL 5 的"华丽".笔者还是喜欢KEIL4的"内敛",主要也还是习惯了.懒得换了.由于工作的  原      ...

  6. c++指针存储应用程序和释放内存的问题

    C++中指针在new和delete操作的时候对内存堆都做了些什么呢.下面解: 1.指针的new操作: 指针在new之后,会在内存堆中分配一个空间.而指针中存放的是这个空间的地址.如: void mai ...

  7. 网络资源(4) - extJS视频

    2014_08_24 http://v.youku.com/v_show/id_XMjk2ODc0MjA4.html?f=7183617 extJS视频教程04——ExtJS框架入门

  8. ftp server来源分析20140602

    ftp  server学习位和源代码分析片 记录自己的第一个开源的分析过程: 从源代码:野狐灯(我接下来的几篇文章是从源头:野狐灯,每个以下哪项不是他们设置.) 20140602 Ftp的源码目录例如 ...

  9. Corel VideoStudio Pro X7(会声会影)

    今天了解一天的视频剪辑方面的知识,自己也动手做了一个. 好啦!下面给大家一些建议: 剪辑软件选择: 1.易学易用.容易上手.模板丰富:会声会影:(需要安装包的可以留言和私信我)2.功能齐全.占用资源少 ...

  10. C++ 对象模型具体评论(特别easy理解力)

    c++对象模型系列 转 一.指针与引用 一 概括 指针和引用,在C++的软件开发中非经常见,假设能恰当的使用它们可以极大的提 高整个软件的效率,可是非常多的C++学习者对它们的各种使用情况并非都了解, ...