javascript中的多线程和订阅/发布方法

Posted

技术标签:

【中文标题】javascript中的多线程和订阅/发布方法【英文标题】:multithreading And Subscribe/Publish approach in javascript 【发布时间】:2009-08-13 13:32:24 【问题描述】:

我了解 javascript 中不支持多线程。我想要一些关于以下场景的专家建议..

我的要求是执行 AJAX 调用,并在成功完成后触发一组事件(以并行更新 UI 的不同部分)

我计划使用订阅/发布模式,是否可以为多个侦听器订阅 AJAX 完成事件。

如果可能的话,我想知道这些listners 是如何在发布时通知的......(以多线程方式或一个一个并行的方式)。

并建议我实现这一目标的最佳方法。我非常感谢您的想法。

编辑::

我知道有像 JQuery 这样的流行框架支持这种模式。但是我可以从头开始开发这个功能(我们有自己的框架)。

【问题讨论】:

你使用什么 Ajax 框架? 没有真正使用任何框架.. 需要在核心 js 框架中实现它.. 见我上面的编辑 【参考方案1】:

我有一个 Request Pooler,可以在这里为您提供良好的开端。 [自从这个答案被接受后,我已经停用了 pooler,转而使用更完整的“AJAX Helper”——链接已更新。]

我不确定它会做你想做的一切(尽管听起来可能很接近)。它很旧,但它有效:

Depressed Press DP_AJAX

它支持多个同时请求超时/重试,每个请求处理程序,占用空间非常小,可以轻松与其他代码组合。

您创建一个池(告诉它允许多少个同时请求),然后向它抛出请求。完成后,它们会调用您指定的任何处理程序。

一个小而完整的使用示例:

        // The handler function
function AddUp(Num1, Num2, Num3) 
    alert(Num1 + Num2 + Num3);
;

    // Instantiate the Pool
myRequestPool = new DP_RequestPool(4);

    // Start the Interval
myRequestPool.startInterval(100);

    // Create the Request
myRequest = new DP_Request(
    "GET",
    "http://www.mysite.com/Add.htm",
    "FirstNum" : 5, "SecondNum" : 10,
    AddUp,
    [7,13]);

    // Add the request to the queue
myRequestPool.addRequest(myRequest);

它是开源的 - 随意切割/折叠/纺锤或破坏它,以满足您的心愿。

吉姆·戴维斯

【讨论】:

感谢 Jim 的分享,它真的很有趣,似乎 DP_requestpool 将同时处理多个 AJAX 请求......但在我的上下文中,我想在完成单个 AJAX 响应时并行触发多个事件... 实际上,允许您同时启动多个 AJAX 请求的相同框架应该可以轻松地用于同时启动多个几乎任何东西。我认为您很容易将对象从特定请求池修改为更通用的“语句池”。【参考方案2】:

This article 非常接近地描述了您要完成的工作。本质上,您只有一个 JavaScript 文件,其中包含一组处理程序/订阅者。每个订阅者都向发布者注册自己(即被添加到处理程序数组中)。然后在 Ajax 调用的 onClose 处理程序中,您将调用一个函数,该函数遍历订阅者并按名称通知每个订阅者:

this.handlers = [];
...
 for(var i = 0; i < this.handlers.length; i++)
  
    this.handlers[i].eventHandler.call(this, eventArgs);
 
...

【讨论】:

感谢 Yalestar 的回复。似乎给定的脚本以顺序方式(一个接一个)调用侦听器。有没有办法模拟这个并行...【参考方案3】:

这可以作为一个轻量级的消息传递框架吗?

function MyConstructor() 
    this.MessageQueues = ;

    this.PostMessage = function (Subject) 
        var Queue = this.MessageQueues[Subject];
        if (Queue) return function() 
                                        var i = Queue.length - 1;
                                        do Queue[i]();
                                        while (i--);
                                    
        

    this.Listen = function (Subject, Listener) 
        var Queue = this.MessageQueues[Subject] || [];
        (this.MessageQueues[Subject] = Queue).push(Listener);
    

那么你可以这样做:

var myInstance = new MyConstructor();
myInstance.Listen("some message", callback());
myInstance.Listen("some other message", anotherCallback());
myInstance.Listen("some message", yesAnotherCallback());

及以后:

myInstance.PostMessage("some message");

将调度队列

【讨论】:

【参考方案4】:

这是可能的,你应该真正使用一个库来避免所有浏览器不兼容。例如,jQuery 提供了 Ajax 功能,允许您在 Ajax 调用完成时执行代码。有关文档,请参阅 here。

【讨论】:

没有真正使用任何框架.. 需要在核心 js 框架中实现它.. 见我上面的编辑.. 这将是仅限 IE 的应用程序.. 我还是会使用框架。这样就容易多了。【参考方案5】:

如果您想在 parralell 中触发函数,请使用以下内容:

this.handlers = [];
...
 for(var i = 0; i < this.handlers.length; i++)
  
    setTimeout(function()this.handlers[i].eventHandler.call(this, eventArgs);,0);
 
...

【讨论】:

以上是关于javascript中的多线程和订阅/发布方法的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中的多线程:线程的优先级和yield方法

iPhone - Tableview 中的多线程 - 可行的方法?

Silverlight 中的多任务和多线程

VBA中的多线程

AsyncTask ProgressBar 更新中的多线程概念 wait() 和 notify()

用于理解 Java 中的多线程的简单任务