zoukankan      html  css  js  c++  java
  • 一步一步实现基于Task的Promise库(三)waitFor方法的设计

    上一篇中我们已经完成了Task.js里面的all和any方法,已经可以完美的解决大部分需求,我们再来看一个需求:

    我们要先读取aa.txt的内容,然后去后台解析,同时由用户指定一个文件,也要读取解析,然后当两个文件都解析完了,我们还要合并两部分内容存到cc.txt中,最后发个通知说ok了。。

    这里的用户是指真正浏览网页的用户,可能是说让用户上传一个文件去读取解析,但是aa.txt是程序定好了的,我们也不希望用户上传文件之后再去读取解析aa.txt,怎么办?如果有一个waitFor方法可以等待另一个任务的完成就好了,请看下面代码:

    1 var taskExp_1 = new Task(readFile, "aa.txt").then(resolveFile, "/service/fileResolve.ashx?file=aa.txt");
    2 var taskExp_2 = new Task(uploadFile, "bb.txt").then(readFile, "bb.txt").then(resolveFile, "/service/fileResolve.ashx?file=bb.txt");
    3 var taskExp_3 = new Task(taskExp_1).waitFor(taskExp_2).then(writeFile, ["cc.txt"]).then(sendMail).start();
    4 $("#btnUpload").click(function (){
    5     taskExp_2.start();
    6 });

    上面代码中的waitFor方法并不会导致taskExp_2的执行,如果用户不点击btnUpload按钮来触发taskExp_2.start(); 那么taskExp_3将一直等待taskExp_2的执行并完成,然后才能进行后面的writeFile。嗯,这样确实可以解决这个头疼的需求,下面我们来看看waitFor方法该如何设计呢?

    先看看下面两句代码有什么区别?

    1 var taskExp3_2 = new Task(readFile, "bb.txt").waitFor(taskExp3_1).then(mergeContent).start();
    2 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(),好处是支持了下面几种写法:

    1 //写法一
    2 var taskExp3_2 = new Task([func1],[func2],[func3]).any().waitFor(task1, task2).then(lastFunc).start(); 
    3 //写法二
    4 var taskExp3_2 = new Task().waitFor(task1, task2).then(lastFunc).start();
    5 //写法三
    6 var task1 = new Task(func1).then([func2],[func3]).all(); //如果没有这个all(),task1的完成就有歧义,是func2,func3都完成才叫完成还是一个完成就叫完成?
    7 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。在下一章我们来实现这些不传参的方法。

  • 相关阅读:
    java环境--JDK和Tomcat在linux上的安装和配置
    转载:jQuery的deferred对象详解
    js 模板引擎 -Art Template
    sublime text的快捷键
    Spring MVC 配置Controller详解
    转:几款免费的图表js插件
    tomcat manager详解
    C#判断一个string是否为数字
    调用摄像头并将其显示在UGUI image上自适应屏幕大小
    unity监测按下键的键值并输出+unity键值
  • 原文地址:https://www.cnblogs.com/lihao123/p/3869793.html
Copyright © 2011-2022 走看看