cc.Class({
extends: cc.Component,
start () {
this.fireOneRound ();
},
fireOneRound () {
cc.log ("fire");
this.prepareNextFire ();
},
prepareNextFire () {
var delay = Math.random ();
this.scheduleOnce (this.fireOneRound, delay);
},
});
For some reason, this will work in the simulator but will trigger only once if launched in the browser.
Is there a reason for that? What is the right way to achieve that?
At first I though the reason is different bindings, but then I saw log in browser (which I dont understand why): “cc.Scheduler#scheduleSelector: Selector already scheduled. Updating interval from: 0 to 0”.
Anyway, you can rewrite your code like this: this.scheduleOnce (this.fireOneRound.bind(this), 1);
I found the reason. In browser scheduleOnce resolves this.fireOneRound as the same selector, even if you run below code
let that = this;
this.scheduleOnce(that.fireOneRound, 1);
But when you run the code
let that = this;
this.scheduleOnce(function() {
that.fireOneRound();
}, 1);
or
this.scheduleOnce (this.fireOneRound.bind(this), 1);
then it will cheat as different selector. That’s strange. I think it’s a bug.
Ah, smart workaround, an anonymous function.
But then with these solutions, I can’t unschedule anymore, as it’s a different selector each time.
But then if I save the last scheduled selector to be able to unschedule it later, it works.
Here is the final code.
cc.Class({
extends: cc.Component,
properties: {
lastScheduledFire: null,
},
start () {
this.fireOneRound ();
},
unscheduleFire () {
this.unschedule (this.lastScheduledFire);
},
fireOneRound () {
cc.log ("fire");
this.prepareNextFire ();
},
prepareNextFire () {
var delay = Math.random ();
this.lastScheduledFire = function () { this.fireOneRound (); };
this.scheduleOnce (this.lastScheduledFire, delay);
},
});
Note there is no need for the “let that = this” if you use an anonymous function.
I would consider it as a bug indeed, because:
- It doesn’t happen in the simulator
- No mention of such a limitation in the documentation
Also, the “Selector already scheduled” message you mentioned disappears if you unschedule (this.fireOneRound) before scheduling it again, but it will still never trigger.