如何在多个其他功能完成后执行Javascript功能?

dgh*_*dgh 19 javascript design-patterns asynchronous node.js

我的具体问题是我需要执行(可能)大量的Javascript函数来准备像批处理文件(每个函数调用将一些信息添加到同一个批处理文件),然后,在完成所有这些调用之后,执行一个发送批处理文件的最终函数(例如,将其作为HTML响应发送).我正在寻找一个通用的Javascript编程模式.

概括问题:鉴于Javascript函数funcA(),funcB()和funcC(),我想找出订购执行的最佳方法,这样funcC只能在执行funcA和funcB之后执行.我知道我可以使用这样的嵌套回调函数:

funcA = function() {
    //Does funcA stuff
    funcB();
}
funcB = function() {
    //Does funcB stuff
    funcC();
}

funcA();
Run Code Online (Sandbox Code Playgroud)

我甚至可以通过传递回调参数使这个模式更加通用,但是,这个解决方案变得非常冗长.

我也熟悉Javascript函数链接,解决方案可能如下所示:

myObj = {}
myObj.answer = ""
myObj.funcA = function() {
    //Do some work on this.answer
    return this;
}
myObj.funcB = function() {
    //Do some more work on this.answer
    return this;
}
myObj.funcC = function() {
    //Use the value of this.answer now that funcA and funcB have made their modifications
    return this;
}
myObj.funcA().funcB().funcC();
Run Code Online (Sandbox Code Playgroud)

虽然这个解决方案对我来说似乎有点清晰,但随着您向计算添加更多步骤,功能执行链变得越来越长.

对于我的具体问题,执行funcA,funcB等的顺序无关紧要.因此,在上面的解决方案中,我在技术上做了比工作要求更多的工作,因为我将所有功能放在一个串行排序中.对我来说最重要的是funcC(用于发送结果或触发请求的某些函数)仅在funcA和funcB完成所有执行后调用.理想情况下,funcC可以某种方式监听所有中间函数调用完成,然后执行?我希望学习一般的Javascript模式来解决这样的问题.

谢谢你的帮助.

另一个想法:也许将共享对象传递给funcA和funcB,当它们完成执行时,标记共享对象,如sharedThing.funcA ="complete"或sharedThing.funcB ="complete"然后以某种方式?当共享对象到达所有字段都标记为完成的状态时执行funcC.我不确定你怎么能让funcC等到这个.

编辑:我应该注意到我正在使用服务器端Javascript(Node.js),我想学习一种模式来解决它只是使用普通的旧Javascript(不使用jQuery或其他库).当然这个问题很普遍,有一个干净的纯Javascript解决方案吗?

pim*_*vdb 8

如果您想保持简单,可以使用基于计数器的回调系统.这是一个允许when(A, B).then(C)语法的系统草案.(when/ then实际上只是糖,但整个系统可以说是.)

var when = function() {
  var args = arguments;  // the functions to execute first
  return {
    then: function(done) {
      var counter = 0;
      for(var i = 0; i < args.length; i++) {
        // call each function with a function to call on done
        args[i](function() {
          counter++;
          if(counter === args.length) {  // all functions have notified they're done
            done();
          }
        });
      }
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

用法:

when(
  function(done) {
    // do things
    done();
  },
  function(done) {
    // do things
    setTimeout(done, 1000);
  },
  ...
).then(function() {
  // all are done
});
Run Code Online (Sandbox Code Playgroud)