zoukankan      html  css  js  c++  java
  • 每周优秀代码赏析—Jscex内核【一】

    一.简介

    Jscex is JavaScript implementation of F#'s Computation Expressions.

    image

    它的灵感的源于F#,它为JavaScript语言提供了一个monadic扩展。Jscex完全使用JavaScript编写,能够在任意支 持ECMAScript 3的引擎里使用(例如各浏览器或Node.js)。Jscex的JIT编译器能在运行时将JavaScript代码编译成Monad形式,无需额外编译步 骤,并内置异步编程类库,可以大大简化JavaScript下的异步编程体验。

    二.原理探析

    先揭开Jscex 内核之前我们先体验一下世界上最简单的一个 Jscex例子:

           var i = 0;
           var countAsync = eval(Jscex.compile("async", function () {
               while (true) {
                   i++;
                   document.getElementById("show").innerHTML = i;
                   $await(Jscex.Async.sleep(1000));
               }
           }))
           countAsync().start();

    一个计数器,从0开始每秒钟加1并显示出来。

    然后我们把countAsync  alert出来,看看Jscex把它compile成什么个样子:

    function () {
        var $$_builder_$$_0 = Jscex.builders["async"];
        return $$_builder_$$_0.Start(this,
            $$_builder_$$_0.Loop(
                function () {
                    return true;
                },
                null,
                $$_builder_$$_0.Delay(function () {
                    i++;
                    (document.getElementById("show")).innerHTML = i;
                    return $$_builder_$$_0.Bind(Jscex.Async.sleep(1000), function () {
                        return $$_builder_$$_0.Normal();
                    });
                }),
                false
            )
        );
    }

    一个匿名函数,然后用eval().start()执行该匿名函数。

    那么上面还能拆开吗?如果作为一个纯粹的.NET或者JAVA程序员,看这段代码肯定很费劲,因为funciton里套funciton,return套return.

    如果你知道javascript的执行顺序的话,上面的函数是还可以拆的:

            var count = 0;
            function doCount() {
                count++;
                document.getElementById("clock").innerHTML = count;
            }
    
            var $$_builder_$$_0 = Jscex.builders["async"];
    
            var delayCount = $$_builder_$$_0.Delay(function () {
                doCount();
                return $$_builder_$$_0.Bind(Jscex.Async.sleep("1000"), function () {
                    return $$_builder_$$_0.Normal();
                });
            });
    
            var loopCount = $$_builder_$$_0.Loop(
                function () {
                    return true;
                },
                null,
               delayCount,
                false
            );
    
            var countAsync = $$_builder_$$_0.Start(this, loopCount);
            
            countAsync.start();

    这样视乎就很清楚它的执行顺序了~~~!

    从上面的代码,我们可以看得出来:我们要做的事情就是:加1显示然后停一秒···加1显示然后停一秒····无限循环下去

    我们发生的事情generator就是:

            var delayCount = $$_builder_$$_0.Delay(function () {
                doCount();
                return $$_builder_$$_0.Bind(Jscex.Async.sleep("1000"), function () {
                    return $$_builder_$$_0.Normal();
                });
            });

    我们要循环的就是delayCount,所以我们把它放到一个loop当中去:

            var loopCount = $$_builder_$$_0.Loop(
                function () {
                    return true;
                },
                null,
               delayCount,
                false
            );

    其中,第一个参数就是while(true),他标志这函数什么时候退出循环。所以比如while(i<3), 它就会编译成function(){return i<3;}

    然后:

    var countAsync = $$_builder_$$_0.Start(this, loopCount);

    这行代码的主要作用是 把这个loop作为一个task赋给Jscex.Async.Task的_delegate,

    可想而知,在这种架构的基础上,可以轻松实现N个loop,就有了异步队列~~~~

    比如:

           var executeAsyncQueue = eval(Jscex.compile("async", function () {
               while (true) {
                   $await(countAsync())
                   $await(otherAsync())
                   $await(Jscex.Async.sleep(1000));
               }
    
           }))
           executeAsyncQueue().start();

    最后,执行countAsync ().start().整个流程就是这样子的,但是到现在为止,我们还没有进入Jscex内核当中去看一看它是怎么实现这些循环和中转的······

    或者你根据上面的思路写出一个伪Jscex出来?我想这个写的过程可以帮你更好的理解Jscex的模式。

    请关注:

    每周优秀代码赏析—Jscex内核【二】

  • 相关阅读:
    element表格添加序号
    ZOJ 3822 Domination(概率dp)
    HDU 3037(Lucas定理)
    HDU 5033 Building(单调栈维护凸包)
    HDU 5037 Frog(贪心)
    HDU 5040 Instrusive(BFS+优先队列)
    HDU 5120 Intersection(几何模板题)
    HDU 5115 Dire Wolf(区间dp)
    HDU 5119 Happy Matt Friends(dp+位运算)
    C++ string详解
  • 原文地址:https://www.cnblogs.com/iamzhanglei/p/2261127.html
Copyright © 2011-2022 走看看