Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript strange generator yield sub function behavior

I'm using MySQL (mysql-co) and ASQ(asynquence) in a simple project to get a better understanding of ES6 generators and yield functions, and I'm stumped on an odd behavior.

Short explanation of asynquence

asynquence (https://github.com/getify/asynquence) provides an easy way for me to run generators in sequence. It can also do pseudo-parallel execution but that's not what I need for now. The structure of function *x(token) is from there. token holds a connection object at [0]. yield token passes control on to the next generator function in sequence.

Code Sample 1 (works)

function *test1(token) {
  var conn = token.messages[0];
  var values = {id:1, dev:1, description:'This is it!'};
  yield conn.query("INSERT INTO version SET ?", values);
  yield token;
}

This works fine. The row described above gets inserted. I didn't know the MySQL driver allowed such a simple looking insert function but it does.

Code Sample 2 (doesn't work)

function *test1(token) {
  var conn = token.messages[0];
  var values = {id:1, dev:1, description:'This is it!'};
  yield subtest1(conn, values);
  yield token;
}
function *subtest1(conn, values) {
  yield conn.query("INSERT INTO version SET ?", values);
}

This doesn't work. The actual code in question for subtest1 is in a model class, so I would prefer not to have it merged in with the controller.

I've tried a bunch of different things around with or without yield on the subtest function.

What's going on?

like image 458
ricfaith Avatar asked May 05 '26 23:05

ricfaith


1 Answers

subtest1(conn, values) is a generator. yielding a generator object does not execute its body. That is, the yielded generator remains suspended, and it would require a call to the next() method for the first yield to be reached. There are no explicit or implicit calls to next() in Code Sample 2, and this is the reason conn.query(...) isn't executed.

How about yield* subtest1(conn, values)? From the linked page:

The yield* expression iterates over the operand and yields each value returned by it.

It will still execute subtest lazily.

An alternative solution is to turn subtest into a regular function and return the result of conn.query(...) (assuming you only need to perform one query):

function subtest1(conn, values) {
    return conn.query("INSERT INTO version SET ?", values);
}
like image 78
vaultah Avatar answered May 08 '26 11:05

vaultah



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!