0

我有以下情况(另见 jsFiddle -> http://jsfiddle.net/sMuWK/):

function CallBackStringHandler() {
    this.callback = function(){return null};
};

CallBackStringHandler.prototype.doTheMagic = function(callback) {
    var result = callback.call(this);
        if(result == null)
            alert("Nothing to handle yet...");
        else
            alert("End the result is: \n\n" + result);
};

function Action(){
    var result = null;
    var max = 10;
    var index = 0;
    var processor = setInterval(function(){
        if(index <= max){ //Processing step
            if(result == null)
                result = "" + index;
            else
                result += index;
            index++;
        } else { //Done
            clearInterval(processor);
            alert(result);
        }
    },10);
    return result;
};

function Run(){    
    var handler = new CallBackStringHandler();
    handler.doTheMagic(Action);
};

Run();

脚本(一个 jQuery 插件)允许您指定一个必须返回字符串的回调。该字符串将由该脚本处理。

到目前为止,一切都很好。

为了性能和保持我的页面响应,我想以多线程方式构建这个字符串。由于这还不是 Web 标准,所以我在 setInterval 的帮助下进行了模拟。

现在才知道,这样做事的本质,不是等待结果。

但是我想不出一种方法来保持响应和快速并将完整结果返回给处理程序。

所以最终结果(在这个例子中)应该显示:012345678910。

任何帮助/线索将不胜感激。

干杯,另一个书呆子。

4

2 回答 2

1

你需要把它反过来。Action不是回调,它不消耗异步结果,而是产生它。doTheMagic另一方面回调,因为它消耗结果(通过alert结果)。

因此,您应该作为回调传递给 ,而不是Action作为“回调”传递给.doTheMagicdoTheMagicAction

function Run() {
    var handler = new CallBackStringHandler();
    Action(function(result) {
        handler.doTheMagic(result);
    });
    // or, alternatively: (only in modern browsers supporting Function.bind)
    Action(handler.doTheMagic.bind(handler));
};

Action接受一个参数并在callback完成后调用它。最后,让我们doTheMagic只接收result. 我叉了你的小提琴,看看

注意:使用 不会获得多线程setInterval,它仍将与脚本的其余部分在同一浏览器线程中运行。如果你真的需要做一些繁重的工作,你可能想要使用 web worker

对于大多数情况,例如像您正在做的那样连接一个字符串,这是矫枉过正的。Worker 生活在一个完全独立的环境中,您只能通过消息与他们进行通信,这给您的应用程序增加了相当多的复杂性。在确定您真的需要多线程方法之前,请确保进行大量测试和基准测试!

于 2013-05-29T09:54:39.463 回答
0

因此,为了得到最终答案,我有点像这样解决了(fork here):

function CallBackStringHandlerBy3rdParty() {};

CallBackStringHandlerBy3rdParty.prototype.doMagic = function(callback) {
    var result = callback.call(this);
    alert(result);
};

CallBackStringHandlerBy3rdParty.prototype.doMyOwnMagic = function(result) {
    if(result.isComplete) {
        this.doMagic(function(){return result.value;});
    } else {
        var that = this;
        result.value += 1;
        if(result.value < 10)
            setTimeout(function(){that.doMyOwnMagic(result);},10);      
        else {            
            result.isComplete = true;
            this.doMyOwnMagic(result);
        }
    }
};

function Run(){    
    var handler = new CallBackStringHandlerBy3rdParty();
    var result = {};
    result.value = 0;
    result.isComplete = false;
    handler.doMyOwnMagic(result);
};

Run();

干杯!

于 2013-05-29T15:19:02.333 回答