0

I just started learning about generators and I'm trying to simulate a async/await request using generators and promises. My first attempt is the code below.

It is always console.log a pending Promise. I do not want to use async/await request because I'm trying to simulate it with generators

Thanks!

function* awaitReq() {
    const val1 =  
        new Promise((resolve, reject) => {
            setTimeout(() => resolve(5))
        }).then((val) => val )
        .catch((err) => "Error");
    
    yield val1;     // it returns the resolve() of my promise

    // second call
    yield val1 * 2;

}

const generator = awaitReq();
const { value, done } = generator.next();
// check if val is a number or error
if(isNaN(value)) {
    console.log(value)
    return value;
}
// otherwise, return the setTimeOut response times 2
console.log(generator.next().value)

Here is my solution:

function getNumber() {
    return new Promise((resolve, reject) => {
        resolve(10);
    }).then((val) => {
        return new Promise((resolve, reject) => {
            resolve(val * 2)
            //reject("Error");
        }).then((val2) => val2);
    }).catch((err) => {
        return err;
    })
}

// function taking a generator fucntion as argument
function run(generatorFn) {
    const iterator = generatorFn();     // create iterator

    const handleNext = (value) => {
        const next = iterator.next(value);
        if(next.done) {
            return next.value;
        } else {
            return Promise.resolve(next.value)
                .then((val) => handleNext(val))
                .catch((err) => handleNext(err));
        }
    }

    handleNext();
}

run(function* () {
    try {
        const result = yield getNumber();
        console.log(result);
    } catch (ex) {
        console.log('Error: ' + ex);
    }
})
myTest532 myTest532
  • 2,091
  • 3
  • 35
  • 78
  • 1
    What's `CustomPromise`? I assume the same as a normal promise? You never `await` it or `then` it, so `yield value` and `yield value * 2` execute before the `setTimeout` resolves. You'll want to `yield` in the callback or `then`. Beyond that, `done` is guaranteed `false` and it's synchronously recursing, which will block the event loop even if you `return callFn(generator.next())`. The code seems overly complex and it's not clear what abstraction this is supposed to accomplish, although I do appreciate you're trying to reinvent the wheel. Are you trying to recreate `await` from scratch? – ggorlen Aug 28 '21 at 19:50
  • I'm sorry, `CustomPromise` is my own implementation of Promise. I just changed the code to use `Promise` instead. Yes and no. I'm trying to simulate `await` to learn more about `generators`. Are you saying that I need to have the generator function inside my setTimeOut then? – myTest532 myTest532 Aug 28 '21 at 20:58
  • 1
    I can't tell what you're trying to do: the code you posted has little to no bearing to your stated goal in the question title. Please add more context. You might also find this helpful: https://hackernoon.com/async-await-generators-promises-51f1a6ceede2 – Jared Smith Aug 28 '21 at 21:10
  • I just updated the code with more details of what I'm trying to do – myTest532 myTest532 Aug 28 '21 at 21:17
  • I'd sort of forget about generators for a minute, beacuse I think you're trying to do too many things at once and getting confused. Generators and async/await are two totally different concepts -- you can't simulate async/await with generators. I'd take a step back and make sure you understand what these concepts do and what "makes sense" in the promises/async world before worrying about generators. After the update, the `val1` promise is never awaited, so `yield val1` is still guaranteed incorrect. This time, it's a promise rather than undefined. – ggorlen Aug 28 '21 at 21:20
  • `async`/`await` are syntactical sugar for creating `then` callbacks that are basically inlined to look like synchronous code and share scope. If what you seem to be trying to do was possible without `async`/`await`, then there'd have been little reason to add these keywords to the language. – ggorlen Aug 28 '21 at 21:22
  • Isn't what they did here: https://hackernoon.com/async-await-generators-promises-51f1a6ceede2 ? – myTest532 myTest532 Aug 28 '21 at 21:27
  • @ggorlen Sure it's possible to simulate `async`/`await` using generator functions, as `yield` uses exactly the same suspension/resumption mechanism. All you need is a runner that actually calls `then` on the yielded promises and registers the next step. See also http://davidwalsh.name/async-generators – Bergi Aug 28 '21 at 21:38
  • ...however despite the technical point being refuted, the point about trying to do too much seems cogent. @myTest532myTest532 if you don't have a solid (and I mean *rock* solid) grasp of both Promises and generators you're going to find it hard to follow combining them to model async/await. I applaud you trying to work through this to get a better understanding (most programmers should do this more) but you seem to need to shore up the foundation you're trying to build atop. – Jared Smith Aug 28 '21 at 21:43
  • Thanks for everyone help. I was able to simulate async/await requests using only generators – myTest532 myTest532 Aug 28 '21 at 22:02
  • @myTest532myTest532 please write a [self answer](https://stackoverflow.com/help/self-answer) if you have a chance and share how you did it. I'm curious, because I don't see how these posts relate to the syntax OP shows -- in the posts shared, the generator function and `yield` is in the caller rather than the callee/library call, so that's a totally different ballgame than `const generator = awaitReq();` where `awaitReq` seems like it's intended to simulate the `await` keyword. But maybe I'm totally mistaken. – ggorlen Aug 28 '21 at 22:04
  • I just edit the post with my solution. It looks like someone closed the post, so I'm not sure if you are able to see it. Yes, you are right, I have to refactor my code – myTest532 myTest532 Aug 28 '21 at 22:07
  • Hmm. It's frowned-upon to put answers in the question. I'll live without it -- interesting thread anyway. – ggorlen Aug 28 '21 at 22:12
  • Yes, Thanks for helping me. I posted the solution. Hopefully, others can see it too – myTest532 myTest532 Aug 28 '21 at 22:21

0 Answers0