Search code examples
javascriptgeneratorco

How to use generators in a proper way with loops


Let's say that we have some data in an array and we need to save each array item in a separate document in mongodb

Here is a code how do I try to do that:

const co = require('co');

const Model = new require('./mongoose').Schema({...});

const data = [
    {...},
    {...},
    {...},
    {...}
];

function* saveData() {
    for (let i = 0; i < data.length; i++) {
        yield (new Model(data[i])).save(() => {
            console.log(i);
        });
    }

    yield function*() { console.log(`xxx`); };
}

co(saveData).then(() => {
    console.log(`The end. Do here some cool things`);
});

I expect that 'the end' will be outputed after all data saved and console would look like this:

0
1
2
3
xxx
The end. Do here some cool things

But what I get is:

0
1
2
xxx
The end. Do here some cool things
3

How to fix the code to :
    1. make the code to output xxx after saving all the items
    2. make the code to outpt The end... really at the end

?


Solution

  • Does this solve your issue? Change

    yield (new Model(data[i])).save(() => {
                console.log(i);
            });
    

    To

    yield (new Model(data[i])).save().then(() => console.log(i));
    

    Basically, since you're yielding a promise, my spidey sense is wondering how the ordering of that works. By using .then, you guarantee that the generator won't yield until the console.log completes.