如何让A和B并行运行?

如何让 A 和 B 并行运行?

async function runAsync(funcName)
{ 
   console.log(' Start=' + funcName.name); 
   funcName(); 
   console.log(' End===' + funcName.name) 
}; 



function A()
{
    var nowDateTime = Date.now();
    var i = 0;
    
    while( Date.now() < nowDateTime + 1000)
      i++;
   
   console.log(' A i= ' + i) ;
}

function B()
{
    var nowDateTime = Date.now();
    var i = 0;
    
    while( Date.now() < nowDateTime + 1000)
      i++;
      
   console.log(' B i= ' + i) ;
}

runAsync(A);
runAsync(B);

控制台显示A先启动,B在A后启动:

 Start=A
 A i= 6515045
 End===A
 Start=B
 B i= 6678877
 End===B

笔记:

我正在尝试对 Chrome/Firefox使用异步,并保持 JS 代码与 IE11 兼容。

此 C# 代码生成代理函数runAsync

    if (isEI())
        Current.Response.Write(" function runAsync(funcName){ setImmediate(funcName); }; ");
    else
        Current.Response.Write(" async function runAsync(funcName){ funcName(); } ");

https://jsfiddle.net/NickU/n2huzfxj/28/

更新。

我的目标是解析信息并准备(索引和添加触发器)以在用户输入后立即响应。在用户查看信息时,后台函数有 3-10 秒的时间执行,后台函数不应阻塞 UI 和鼠标和键盘响应。这是所有浏览器的解决方案,包括IE11。

创建了一个新插件来模拟空闲时间期间 funcRun 的并行执行。

原始代码示例:

 $("input[name$='xxx'],...").each( function(){runForThis(this)}, ticksToRun );

使用插件的更新代码:

  $(document).zParallel({
        name: "Example",
        selectorToRun: "input[name$='xxx'],...",
        funcRun: runForThis
    });

插入。

(function ($)
{
// Plugin zParallel

    function zParallel(options)
    {
        var self = this;

        self.defaults = {
            selectorToRun: null,
            funcRun: null,
            afterEnd: null,
            lengthToRun: 0,
            iterScheduled: 0,
            ticksToRun: 50,
            showDebugInfo: true
        };

        self.opts = $.extend({}, self.defaults, options);
    }

    zParallel.prototype = {

        init: function ()
        {
            var self = this;

            var selector = $(self.opts.selectorToRun);
            self.lengthToRun = selector.length;

            if (self.lengthToRun > 0)
            {
                self.arrayOfThis = new Array;
                selector.each(function ()
                {
                    self.arrayOfThis.push(this);
                });
                self.arrayOfThis.reverse();
                self.opts.iterScheduled = 0;
                self.whenStarted = Date.now();
                self.run();
                return true;
            }
            else
            {
                this.out('zParallel: selector is empty');
                return false;
            }
        },

        run: function () 
        {
            var self = this;
            var nextTicks = Date.now() + self.opts.ticksToRun;
            var _debug = self.opts.showDebugInfo;

            if (self.opts.iterScheduled === 0)
            {
                nextTicks -= (self.opts.ticksToRun + 1);   // Goto to Scheduling run
            }

            var count = 0;
            var comOut = "";
            while ((self.lengthToRun = self.arrayOfThis.length) > 0)
            {
                var curTicks = Date.now();

                if (_debug)
                {
                    comOut = self.opts.name + " |" + (curTicks - self.whenStarted)/1000 + "s| ";
                    if (self.opts.iterScheduled === 0)
                        this.out("START " + comOut + " remaining #" + self.lengthToRun);
                }

                if (curTicks > nextTicks)
                {
                    self.opts.iterScheduled++;

                    if ('requestIdleCallback' in window)
                    {
                        if (_debug)
                            this.out(comOut + "requestIdleCallback , remaining #" + self.lengthToRun + " executed: #" + count);
                        window.requestIdleCallback(function () { self.run() }, { timeout: 1000 });
                    } else
                    {
                        if (_debug)
                            this.out(comOut + "setTimeout, remaining #" + self.lengthToRun + " executed: #" + count);
                        setTimeout(function (self) { self.run()}, 10, self);
                    }
                    return true;
                }

                var nexThis = self.arrayOfThis.pop();
                self.opts.funcRun(nexThis);
                count++;
            }

            if (self.opts.afterEnd!== null)
               self.opts.afterEnd();

            if (_debug)
                this.out("END " + comOut + " executed:  #" + count);

            return true;
        },
        out: function (str)
        {
            if (typeof console !== 'undefined')
                console.log(str);
        }
    };


    $.fn.zParallel = function (options)
    {
        var rev = new zParallel(options);
        rev.init();
    };
})(jQuery);

//例子。

(function ($)
{

    var tab1 = $('#tbl1');
    for (i = 0; i < 1000; i++)
        $("<tr>"+
        "<td>#" + i + "</td>"+
        "<td><input id='a_" + i + "' value='" + i + "' >"+
        "</td><td><input id='b_" + i + "' value='" + i + "' ></td></tr>")
            .appendTo(tab1);

    $(document).zParallel({
        name: "A",
        selectorToRun: "input[id^='a_']",
        funcRun: function (nextThis)
        {
            var $this = $(nextThis);

            var nowDateTime = Date.now();
            var i = 0;
            while( Date.now() < nowDateTime + 2)
                  i++;

            $this.val( i );
            if (i > 100)
                $this.css('color', 'green').css('font-weight', 'bold');
            else
                $this.css('color', 'blue');
        }
    });


    $(document).zParallel({
        name: "B",
        selectorToRun: "input[id^='b_']",
        funcRun: function (nextThis)
        {
            var $this = $(nextThis);

            var nowDateTime = Date.now();
            var i = 0;
            while( Date.now() < nowDateTime + 2)
                  i++;

            $this.val( i );
            
            if (i > 100)
                $this.css('background', '#BBFFBB');
            else
                $this.css('background', '#FFBBBB');
        }
    });

})(jQuery);

https://jsfiddle.net/NickU/1xt8L7co/59/

回答

这两个示例函数只是在同一个“线程”上一个接一个地同步执行(JS 实际上只有一个线程可用于此类脚本)。

这里的使用async无关紧要,因为函数 A 中没有发生真正的异步操作——它只是一个繁忙的 while 循环——所以它在执行可以移动到其他任何东西之前完全完成。

如果函数 A 调用了实际的异步操作(例如 HTTP 请求 - 不仅仅是封装在async函数中的同步操作),则函数 B 可能有机会启动(在这种情况下,B 将在执行返回到A,因为 B 也只包含一个同步的、繁忙的 while 循环)。

可以使用允许在后台线程(实际独立线程)上运行的 WebWorkers 来实现并行处理。


以上是如何让A和B并行运行?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>