简体   繁体   English

事件监听器Javascript

[英]Event listener Javascript

I have 3 instances of the class Foo() . 我有3个类Foo()实例。 Let's call them foo1, foo2 and foo3 . 我们称它们为foo1, foo2foo3 By default, the propriety isReady of Foo() is false . 默认情况下, Foo() isReadyfalse In the constructor of Foo() , there is an asynchrousnous method that sets isReady to true. Foo()的构造函数中,有一个异步方法将isReady设置为true。 For instance, I could be setTimout with different duration. 例如,可以将setTimout为不同的持续时间。 After I instantiate these 3 instance, there is function called: startMainAction() that should be called only after foo1.isReady = true and foo2.isReady = true and foo3.isReady = true Given that the asynchronous function is undetermined, (it could be random duration), there is no way for sure the order at which the foo instances will have their propriety isReady set to true . 在实例化这3个实例之后,有一个名为: startMainAction()函数仅应在foo1.isReady = truefoo2.isReady = truefoo3.isReady = true之后foo1.isReady = true鉴于该异步函数未确定,(可以随机持续时间),无法确定foo实例的适当性的顺序isReady设置为true Hence, I do not think I could use callbacks to call startMainAction . 因此,我认为我不能使用回调来调用startMainAction

How can that be achieved? 如何实现?

  class Foo{ constructor(n){ this.isReady = false; setTimeout(()=>{ this.isReady = true; console.log('I am ready '+n); }, Math.random()*1000) } } const foo1 = new Foo(1) const foo2 = new Foo(2) const foo3 = new Foo(3) function startMainAction(){ console.log('All fooes must be ready before I was called') } 

One option is to add a method which adds a callback to call once you set isReady to true: 一种选择是添加一个方法,该方法将将isReady设置为true时添加要调用的回调:

onReady(callback) {
  this.readyCallbacks.push(callback);
}

Then, with those three instances, call onReady with the resolve of a Promise, and call Promise.all on those three Promises: 然后,这三个实例,调用onReadyresolve许诺,并呼吁Promise.all就这三项承诺:

const foos = [foo1, foo2, foo3];
Promise.all(foos.map(foo => new Promise(resolve => foo.onReady(resolve))))
  .then(startMainAction);

 class Foo { constructor() { this.readyCallbacks = []; this.isReady = false; setTimeout(() => { this.isReady = true; console.log('I am ready'); this.readyCallbacks.forEach(callback => callback()); }, Math.random() * 1500) } onReady(callback) { this.readyCallbacks.push(callback); } } const foo1 = new Foo() const foo2 = new Foo() const foo3 = new Foo() function startMainAction() { console.log('All fooes must be ready before I was called') } const foos = [foo1, foo2, foo3]; Promise.all(foos.map(foo => new Promise(resolve => foo.onReady(resolve)))) .then(startMainAction); 

I suppose you could also pass the readyCallback in the constructor, which would result in less code, but that doesn't seem quite appropriate, because a Foo (say, foo4 ) may not need a readyCallback , and a readyCallback isn't necessary to create an instance, it's a handler that other parts of the code request to add to an instance. 我想您也可以在构造函数中传递readyCallback ,这将导致更少的代码,但这似乎不太合适,因为Foo (例如foo4 )可能不需要readyCallback ,而且readyCallback 不需要创建一个实例,它是代码的其他部分请求添加到实例的处理程序。 (for example, if you had two parts of the code which had to listen for the isReady of foo1 , you would need something like this onReady method.) (例如,如果您有部分代码必须监听foo1isReady ,则需要类似onReady方法的东西。)

Have the constructor method create a promise that will resolve when the condition to make the object ready happens. 让构造函数方法创建一个Promise,该条件将在使对象准备就绪的条件发生时解决。

Then get the promises from all of the instances and wrap them with Promise.all so they wait for all of them. 然后从所有实例中获取承诺,并用Promise.all包装它们,以便它们等待所有承诺。

 class Foo { constructor() { this.isReady = false; this.isReadyPromise = new Promise( res => setTimeout( () => { console.log("I am ready"); this.isReady = true; res(true); }, 1000 + 1000 * (Math.floor(Math.random() * Math.floor(3))) ) ) } } const foo1 = new Foo(), foo2 = new Foo(), foo3 = new Foo(); Promise.all([ foo1.isReadyPromise, foo2.isReadyPromise, foo3.isReadyPromise ]).then(() => { console.log("All 3 are ready") }); 

You can add all of your instances of Foo into a list, an array or anything that you can iterate over. 您可以将所有Foo实例添加到列表,数组或任何可以迭代的内容中。 Then do something along the lines of 然后按照以下步骤做一些事情

let foos = [foo1, foo2, foo3];

function WaitUntilReady(callback) {
    let ready = true;
    foreach (let foo of foos) {
        if ( !foo.isReady ) {
            ready = false;
            break;
        }
    }

    if ( ready ) {
        callback(); 
    } else {
        setTimeout(WaitUntilReady, 100); //100 miliseconds until next check
    }
}

WaitUntilReady(function() {
    //every instance is ready
});

Edit: using Promises seems more fancy, not sure if it really is. 编辑:使用Promises似乎更花哨,不确定是否确实如此。 I'm not that much of a javascript developer so i did not even think of using them 我不是一个JavaScript开发人员,所以我什至没有想到要使用它们

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

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