簡體   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