[英]Class with common callback in javascript
i want to build a javascript class to register several different functions to execute a single common callback, all registered functions should execute asynchronously and then once all of them are finished, it should execute the defined callback function . 我想构建一个javascript类来注册几个不同的函数以执行一个通用回调,所有注册的函数应异步执行,然后在所有这些函数完成后,便应执行定义的回调函数 。
We should also be able to define a maximum time before the callback function executes. 我们还应该能够定义回调函数执行之前的最长时间 。 For example if we define that as 3000 and it takes more than 3000 ms for all registered functions to return, it should proceed to execute callback function even though the ajax functions have not finished retuning.
例如,如果我们将其定义为3000,并且所有注册的函数都需要3000毫秒以上的时间才能返回,则即使ajax函数尚未完成重新调整,它也应继续执行回调函数。
To be clear, this code needs to be flexible, standalone and reusable 需要明确的是,此代码必须灵活,独立且可重用
To assume that any function that we register will implement a call to a function that we define at some point within it mark its completion. 假定我们注册的任何函数都将实现对我们在其中定义的某个点的函数的调用,以表示该函数已完成。 for eg.
例如 at the end of my function i'll enter myClass.markDone() to let the class know the function has completed executing
在函数的末尾,我将输入myClass.markDone() ,让类知道该函数已完成执行
Is it possible using javascript or with angular.js and without jquery? 是否可以使用javascript或使用angular.js而不使用jquery?
To achieve this take a look at these angular built in modules: 为此,请看一下这些内置的angular模块:
https://docs.angularjs.org/api/ng/service/ $q https://docs.angularjs.org/api/ng/service/ $ q
https://docs.angularjs.org/api/ng/service/ $timeout https://docs.angularjs.org/api/ng/service/ $ timeout
Here is an example implementation on plunkr: 这是在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 http://plnkr.co/edit/hNo9kJmKIR4hEoNk9pP2?p=preview
iam not sure this will work, am not tested. 我不确定这是否有效,未经测试。 this may give you some idea.
这可能会给您一些想法。
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" );
}
I asked for clarification in a comment already, but I went ahead and started drafting a solution. 我已经在评论中要求澄清,但我继续进行并开始草拟解决方案。 Here's what I came up with, hope this is what you meant:
这是我想出的,希望这就是您的意思:
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
},
};
Here's how you would use this: 这是您的使用方式:
AsyncBatch
. AsyncBatch
的实例。 .add()
as many times as you want, passing a function. .add()
,并传递一个函数。 This functions should expect a single parameter, which is the callback it should invoke when its job is done. .start()
on the AsyncBatch
instance. AsyncBatch
实例上调用AsyncBatch
.start()
。 It will execute all runnables asynchronously, as well as start a timer. .allDone
will cancel the timer and execute .finish()
. .allDone
将取消计时器并执行.finish()
。 .finish()
, and sets the timerId
to 0 so that .finish()
won't be called again when the runnables all finish. .finish()
,并将timerId
设置为0,以便当所有可运行对象完成时不会再次调用.finish()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.