【问题标题】:Callback pattern for handling everything in the body of a function用于处理函数体中所有内容的回调模式
【发布时间】:2014-06-25 21:59:07
【问题描述】:

当我的函数包含在其体内发出新线程/工作者的内容时,使用什么正确模式?为了更好地说明问题,请查看以下 jsFiddle:http://jsfiddle.net/Dx29q/

function write(text){
    var obj = document.getElementById('foo');
    obj.innerHTML = obj.innerHTML + text + ' ';
}

function test(a,b,callback){

    write(a+b); //A
    setTimeout(function(){write(a-b);},1000); //B    
    write(a*b); //C

    callback(); //D
}

test(3,2,function(){

    write("Finished!");
});

问题在于执行操作的实际顺序是 ACDB。我只想在回调完成之前函数中的所有内容之后执行回调。我必须使用纯 JavaScript(甚至不是库)。我正在努力寻找任何好的教程来解决使用回调时的高级情况,只有完整的基础知识。

感谢您的建议!

编辑如下:

  • 我需要达到的顺序是 (ABC)D,我不关心 ABC 之间的顺序,只要 D 完全完成后才执行。

  • setTimeout 只是一个例子,为了更好地想象一个调用 foo()、bar()、baz() 和 callback() 的函数。 foo、bar、baz需要分别同时执行,后面还要调用callback()。

【问题讨论】:

  • 您的目标执行顺序是什么? ACBD?
  • @RobbyCornelissen ABCD,或者更准确地说,我不关心 ABC 之间的顺序,只要 D 仅在它们之后执行。
  • 那么超时如何处理?
  • @RobbyCornelissen 我也想知道 :) 必须有一种方法来确定触发回调函数是否安全。
  • 如果不重建像promises 这样的东西,你唯一真正的选择是拥有一个你不断传递大量onComplete-callbacks 的结构。特别是如果执行的函数本身包含异步代码。

标签: javascript callback


【解决方案1】:

您应该执行额外的检查,即如下所示:

function write(text){
    var obj = document.getElementById('foo');
    obj.innerHTML = obj.innerHTML + text + ' ';
}

function test(a,b,callback){
    var finished = false,
        interval;

    write(a+b);
    setTimeout(function(){write(a-b); finished = true;},1000);    
    write(a*b);

    interval = setInterval(function(){
        if (finished) {
            callback();
            clearInterval(interval)}
    }, 100);
}

test(3,2,function(){

    write("Finished!");
});

http://jsfiddle.net/U9K5g/1/

另外,阅读有关 Promises/A+ 的内容可能对您有用

很好的例子是 - http://www.html5rocks.com/en/tutorials/es6/promises/

【讨论】:

  • 我正在考虑这样的事情,但是当您每次需要等待某事时创建一个间隔时,感觉有点脏。但如果没有人想出更好的模式,我可能会接受这个。到目前为止谢谢;)
  • 是的,这是一个棘手的解决方案。建议您阅读 Promises - 这是最好的解决方案。
【解决方案2】:

这将为您提供 ABCD 的执行顺序。不知道你为什么要这样做……

function test(a, b, callback) {
    write(a+b); //A
    setTimeout(function() {
        write(a-b); //B
        write(a*b); //C
        callback(); //D
    }, 1000);
}

【讨论】:

  • 是的,你是对的,但这并不检查函数是否完成。在您发布的代码中,您只是在执行超时之前不调用任何内容。问题是这只是一个例子——想象一下你有函数 foo()、bar()、baz() 并且你必须同时执行它们的情况。这就是为什么我要问一个模式来解决这个问题,而不是“如何修复我的代码”。这并不能解决我的问题,不过 +1,它可能会帮助很多用户。
  • 明白了。在这种情况下,我不得不接受@DmitryVolokh 的建议:要么在变量中维护状态并临时检查它,要么尽可能使用 Promises。
猜你喜欢
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 2010-10-30
  • 2018-08-20
  • 2017-12-14
相关资源
最近更新 更多