如何让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 来实现并行处理。