繁体   English   中英

在JavaScript中具有常见回调的类

[英]Class with common callback in javascript

我想构建一个javascript类来注册几个不同的函数以执行一个通用回调,所有注册的函数应异步执行,然后在所有这些函数完成后,便应执行定义的回调函数

我们还应该能够定义回调函数执行之前的最长时间 例如,如果我们将其定义为3000,并且所有注册的函数都需要3000毫秒以上的时间才能返回,则即使ajax函数尚未完成重新调整,它也应继续执行回调函数。

需要明确的是,此代码必须灵活,独立且可重用

假定我们注册的任何函数都将实现对我们在其中定义的某个点的函数的调用,以表示该函数已完成。 例如 在函数的末尾,我将输入myClass.markDone() ,让类知道该函数已完成执行

是否可以使用javascript或使用angular.js而不使用jquery?

为此,请看一下这些内置的angular模块:

https://docs.angularjs.org/api/ng/service/ $ q

https://docs.angularjs.org/api/ng/service/ $ timeout

这是在plunkr上的示例实现:

qAllWithTimeout([
    makePromise(function(callback) {
      // Mock async call 1
      setTimeout(callback, 200);
    }),
    makePromise(function(callback) {
      // Mock async call 2
      setTimeout(callback, 500);
    }),
    makePromise(function(callback) {
      // Long running mock async call 2
      setTimeout(callback, 10500);
    })
  ], 3000)
    .then(function() {        
        $scope.state = 'ready';
    })

http://plnkr.co/edit/hNo9kJmKIR4hEoNk9pP2?p=preview

我不确定这是否有效,未经测试。 这可能会给您一些想法。

function TestFun(callback, timeout){
    this._callback = callback;
    this._timeout = timeout;
    this._forceFinish = false;
    this.fun_list = [];
    this.RegisterFun = function(fun){
        this.fun_list.push(fun);
    };

    this.startCount = -1;
    this.finishCount = 0;

    this.timeOutFunction= function(){
        this.startCount++;
        fun_list[this.startCount]();
        this.commonCallback();
    }
    this.Start = function(){
        for(var i=0; i <this.fun_list.length ;i++){
            setTimeout( this.timeOutFunction, 0);
        }
        setTimeout( this.watcherFun, 1 );
    };

    this.commonCallback = function(){
        if( this._forceFinish){
            this._callback();
        }else{
            this.finishCount++;
            if(this.finishCount == this.fun_list.length ){
                this._callback();
            }
        }
    }

    this.watcherFun = function(){
        if( this._timeout !=0 ){
            this._timeout-1;
            setTimeout( this.watcherFun, 1 );
        }else{
            this._forceFinish = true;
            this.commonCallback();
        }
    }
}

//usage

var funMngr = new TestFun(finalFun, 60 * 1000);
funMngr.RegisterFun ( fun1 );
funMngr.RegisterFun ( fun2 );
funMngr.RegisterFun ( fun3 );
funMngr.Start();

function finalFun(){
    alert("all functions executed" );
}

我已经在评论中要求澄清,但我继续进行并开始草拟解决方案。 这是我想出的,希望这就是您的意思:

var AsyncBatch = function() {
    this.runnables = new Set();
};

AsyncBatch.prototype = {
    runnables: null,
    timeoutId: 0,

    add: function(runnable) {
        this.runnables.add(runnable);
    },

    start: function() {
        this.timeoutId = window.setTimeout(this.timeout.bind(this), 3000);

        let promises = [];
        for (let runnable of this.runnables) {
            promises.add(new Promise(resolve => {
                runnable(resolve);
            }));
        }
        Promise.all(promises).then(() => this.allDone());
    },

    allDone: function() {
        if (this.timeoutId == 0) return;
        window.clearTimeout(this.timeoutId);
        this.finish();
    },

    timeout: function() {
        this.timeoutId = 0;
        this.finish();
    },

    finish: function() {
        // Do something here when all registered callbacks are finished OR the batch timed out
    },

};

这是您的使用方式:

  1. 创建一个AsyncBatch的实例。
  2. 根据需要多次调用.add() ,并传递一个函数。 此函数应包含一个参数,即完成工作后应调用的回调。
  3. AsyncBatch实例上调用AsyncBatch .start() 它将异步执行所有可运行对象,并启动计时器。
  4. 如果可运行对象在计时器用尽之前全部完成,则.allDone将取消计时器并执行.finish()
  5. 如果计时器在可运行对象之前用完,它将执行.finish() ,并将timerId设置为0,以便当所有可运行对象完成时不会再次调用.finish()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM