Coroutine in Cocos Ceator?

A coroutine allows you to spread tasks across several frames. In Unity, a coroutine is a method that can pause execution and return control to Unity but then continue where it left off on the following frame.

I wrote some script to clone this.
I have some issues like : i want to create many coroutine easier, stop coroutine immediately.
may be can you complete it or any better idea!

sleep(seconds: number) {
   return new Promise((resole) => setTimeout(resole, seconds * 1000));
}
async startCountDownAsync() {
    await this.sleep(1);
    this.startCountDown();
}
 async startCountdown() {
    this._isStartCountDown = false;
    await this.sleep(1);
    this.checkEndGame();
    this._isStartCountDown = true;
}
update(dt){
    if (this._isStartCountDown) {
       this.startCountdown();
    }
}

async await

Not enough my friend :slight_smile:
Let’s try to solve this with coding.

It is recommended to see the Typescript document

A coroutine allows you to spread tasks across several frames. In Unity, a coroutine is a method that can pause execution and return control to Unity but then continue where it left off on the following frame.

I wrote some script to clone this.
I have some issues like : i want to create many coroutine,or stop coroutine immediately.
may be can you complete it or any better idea!

sleep(seconds: number) {
   return new Promise((resole) => setTimeout(resole, seconds * 1000));
}
async startCountDownAsync() {
    await this.sleep(1);
    this.startCountDown();
}
 async startCountdown() {
    this._isStartCountDown = false;
    await this.sleep(1);
    this.checkEndGame();
    this._isStartCountDown = true;
}
update(dt){
    if (this._isStartCountDown) {
       this.startCountdown();
    }
}

sleep function need add async

You don’t understand.

It is too complicated, I can’t.

This is a test ts code!

const {ccclass, property} = cc._decorator;

@ccclass
export default class Helloworld extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;

    @property
    text: string = 'hello';

    start () {

        this.startCountDownAsync();
    },

    async sleep(seconds){
		return new Promise((resole) => setTimeout(resole, seconds * 1000));
    },

    async startCountDownAsync() {
	    await this.sleep(1);
	    this.startCountDown();
	},

    update(dt){
		if (this._isStartCountDown) {
	       this.startCountDown();
	    }
    },

    async startCountDown() {
	    this._isStartCountDown = false;

	    await this.sleep(1);

	    cc.log('checkEndGame')
	    //this.checkEndGame();

	    this._isStartCountDown = true;
	},
}

very good

I think do not need async before return promise func.It’s
The problem i need is : create many coroutine easy,and how to stop coroutine immediately.

js and ts no real coroutine。You need to stop asynchronous logic through code control, such as this

start () {

    this.startCountDown();
},

async sleep(seconds){
	return new Promise((resole) => setTimeout(resole, seconds * 1000));
},

async startCountDown() {
    this._isStartCountDown = true;

    await this.sleep(1);

    if(this._isStartCountDown){

	    cc.log('checkEndGame')
	    //this.checkEndGame();

	    this.startCountDown();
    }
},

stopCountDown(){
	this._isStartCountDown = false;
},
1赞

thanks for your idea.
I will try another idea hope the better way :slight_smile:
Thanks!

How about

stoppable (task: Promise): Promise {
    return new Promise((resolve, reject) => {
        task.catch(e => reject(e));
        task.then(value => {
            // check component destroyed state or use any other condition to stop coroutines
            if (this.isValid) {  
                resolve(value);
            }
            else {
                // DONT CALLBACK
            }
        });
    });
}

async start () {
    await foo();  // unstoppable
    console.log('output');

    await stoppable(bar);
    console.log('never output if destroyed');
}

You can even write a decorator, like

@stoppable
async foo () {
}

async start () {
    await foo();
    console.log('never output if destroyed');
}
1赞
function* startCountdown() {
  this._isStartCountDown = false;
  yield;
  this.checkEndGame();
  this._isStartCountDown = true;
}

const manager = startCountdown();
manager.next(); // this._isStartCountDown === false
// sleep or do anything....
manager.next(); // this._isStartCountDown === true
3赞

个人觉得 rxjs 比 async & await 好用多了.

这些异步语法糖乍一看很美好, 实际应用起来很容易陷入状态错乱问题.

rxjs 一个 takeUntil 可以避免大部分状态错乱问题.

Thank you. The great idea :smiley:
I will try!

Wow, i don’t think ts have this thing!
I will try it!
Thank you!

Can i ask a question about : what’s better way to stop/delete a Generator function?

Consume it. Or let your generator itself return at some where.

1赞