What is preventing yield from resolving a promise?

Here is the code snippet I am working with:

object = {
    getPastEvents: () => Promise.resolve([1,2,3])
}

function* fetchPastEvents() {
    const values = yield object.getPastEvents()
    console.log(values)
}

const events = fetchPastEvents()
events.next()
events.next()

My goal now is to figure out how to update the function getPastEvents so that it returns a specific set of values. Currently, the values are undefined. I initially believed that using yield would handle resolving a promise similar to async await.

Answer №1

When you invoke the .next method, you continue the execution of the generator function. If you wish to resume it with a specific value, you can pass that value into the .next method. To replicate the behavior of redux-saga in resolving promises and then resuming the generator, you'll need to retrieve the promise yielded by the initial call to .next, wait for the promise to resolve using its .then method, and then call .next with the resolved value.

const object = {
  getPastEvents: () => Promise.resolve([1,2,3])
}

function* fetchPastEvents() {
  console.log("entry")
  const values = yield object.getPastEvents()
  console.log(values)
}

const iterator = fetchPastEvents()
const promise = iterator.next().value;
promise.then(val => iterator.next(val))

I would advise against trying to implement this manually. If this is indeed a saga as you mentioned, consider running it through redux saga where this functionality is included. Alternatively, you could explore the co library which offers similar features.

Answer №2

My understanding was that using yield is similar to resolving a promise like with async await.

In reality, yield is specifically used for pausing a generator function, causing the function's execution to stop at that point. It then returns the expression on the right side to the caller of .next(), and waits until the next .next(value) call to continue executing. This process can seem asynchronous, but it is unrelated to utilizing async / await. Although, it is possible to yield a promise and resume execution once the promise resolves by calling .next(value):

 async function co(generator) {
   let iterator = generator();
   let done, value;
   do {
     ({ done, value } = iterator.next(await value);
   } while(!done);
   return value;
}

This functionality can be implemented in such a way:

 co(function* doAsync() {
   let result = yield somePromise();
   console.log(result);
});

However, it may not always be practical given the existence of async generators designed precisely for this purpose.

Answer №3

When using yield in a generator, it does not always wait until a promise is fulfilled.

In order to make the example work, you need to write code that invokes the next method of an object implementing the iterable protocol.


function runGenerator(asyncGen) {
    const gen = asyncGen();
    let returnValue;

    (function iterate(value){
        returnValue = gen.next(value);

        if(!returnValue.done) {
            returnValue.value.then(iterate);
        }
    })();
}

const object = {
    getPastEvents: () => Promise.resolve([1,2,3])
};

runGenerator(function*() {
    const values = yield object.getPastEvents();
    console.log(values);
});

Please note that this is a basic implementation and more conditions should be checked for use in actual projects.

Instead of creating your own implementation, consider using the co module.


It's important to know that Async & Await follows a similar approach, both requiring promisified APIs.

For Async & Await to work, ensure your JavaScript engine supports it, or transpile the code to work on older engines.

Generators will work on most modern JavaScript engines, as it is based on an older specification (ES6).

Transpiling Async & Await can lead to larger code size, which may impact content optimization goals.

A key difference between ES6 Generators and ES7 Async & Await is that ES6 Generators cannot use Arrow functions, which may be crucial in certain situations (as you need to store the "this" reference before entering the generator context), whereas ES7 Async Functions can utilize them.

Note that while ES7 Async & Await is syntactic sugar for promises, ES6 generators are not.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Loading content synchronously

Could you assist me in finding a solution to synchronize the loading of pages and elements? Currently, my code looks like this: $(Element).load(File); ... other commands... window.onload = function () { Update_Elements(Class, Content); } Everything ...

The changes to the position are being reflected in the debug console, yet my DOM remains stagnant

I'm currently working on developing a JavaScript clicker game, but I've encountered an issue with the gem animations. Despite debugging and confirming that the position is updating, the gems do not visually fall down after being clicked. Below is ...

Using jQuery to handle nested div elements and triggering a click event only once when the inner div is clicked

I have a situation where I have nested divs. When the inner div (closeme) is clicked, I do not want the click event of the outer div (container) to be triggered. How can I achieve this? html <div id="container"> content <div id="closeme">< ...

What is the best way to render images on the server side in React?

I've got this snippet of code residing in my server/server.js import path from 'path'; import fs from 'fs'; import React from 'react'; import ReactDOMServer from 'react-dom/server'; import express from 'ex ...

Unlock the ability to retrieve the context element from a dynamically bound event within the event handler using jQuery

I have a chunk of HTML that gets inserted into the page and is connected to a click event handler. Here's an example in the code snippet below: var matchMore = $(".match-more-btn"); matchList.on("click", matchMore, function() { var self = $(this); ...

What is the simplest way to run a basic express js script?

I am encountering an issue while trying to run a basic express script in JavaScript. Every time I attempt to execute the script, I keep getting an error message stating that "require is not defined". Below are snippets of the code. Thank you! const expres ...

Using bootstrap can alter the positioning of elements that have margins relative to other elements

After exploring suggestions from my previous post on Stack Overflow, I have implemented a modified version to animate drag movements. While the HTML5 draggable attribute can achieve dragging, its limitations and side effects are something I aim to avoid. ...

Retrieving outcomes from a sequence of callback functions in Node.Js

I've been struggling to get my exports function in Node.Js / Express app to return the desired value after going through a series of callback functions. I've spent hours trying to fix it with no success. Can someone provide some guidance? Here is ...

Struggling with modifying class in HTML using JavaScript

I've been attempting to replicate a JavaScript code I came across on the internet in order to create a functioning dropdown menu. The concept is quite straightforward - the div class starts as xxx-closed and upon clicking, with the help of JavaScript, ...

Combine the values in the rows over a period of time

I have a set of three times in the format of Minute:Seconds:Milliseconds that I need to add together to get the total time. For example, let's say I have: 0:31.110 + 0:50.490 + 0:32.797, which equals 1:54.397. So how can I achieve this using JavaScr ...

Can I expect the same order of my associative array to be preserved when transitioning from PHP to Javascript?

While using PHP, I am executing a mysql_query with an ORDER BY clause. As a next step, I am going through the results to construct an associative array where the row_id is set as the key. After that, I am applying json_encode on that array and displaying ...

What is behind the peculiar reaction when checkboxes are used in React?

In this demo, what is causing the button to disable only after both checkboxes have been checked? Is the button not initially displayed as disabled due to the way state behaves in react? The example consists of two checkboxes: I have read and agree to te ...

What purpose does the class serve in typescript?

This is a unique version of app.component.ts in the Angular Tour of Hero tutorial. import { Component } from '@angular/core'; export class Superhero{ name : string; id : number; } const SUPERHEROES : Superhero[] = [ {name : 'Wonder ...

"HTML and JavaScript: The search functionality fails when trying to search for a string that is sourced from an array

Could someone assist me with a comparison issue I'm encountering? I am trying to use the includes() method to compare a list in a table with a list of names stored in a string. Strangely, when I hardcode the string directly into the includes() method, ...

The bxSlider reloadSlider() function is not defined once the page has finished loading

I am currently working on developing an interactive upload and refresh gallery using AJAX and jQuery. The application allows for the upload of multiple images through drag & drop. After uploading, I need to visualize how the new gallery will appear with t ...

Is it possible to add animated text using anime.js?

var elements = document.querySelectorAll('.content'); anime({ targets: elements, content: 100, }); <script src="https://raw.githubusercontent.com/juliangarnier/anime/master/lib/anime.min.js"></script> <span class="content"> ...

Unable to display notifications within the modal using Notistack MUI in React JS

Hey there, I'm currently utilizing react in combination with MUI. To display notifications, I've integrated a library called notistack. My goal is to show an error message in a dialog if there's a failure in the API response. Here's the ...

The value of a Highcharts series does not match that of a Data Source

Encountering an issue with Highcharts where the value of this.y does not reflect the data source. The discrepancy is apparent in the image below. Uncertain if this is a bug or user error. Screenshot illustrating the problem You can view my Demo here: htt ...

Steps to store radio button selections in local storage

I have a quiz that includes radio buttons, and I need to save the answers on my local storage. However, I am currently stuck and unsure of what else to do. I am learning, so please don't be too hard on me. Thank you! Here is the code I have written s ...

Issue with .html causing .hover to malfunction

Attempting a basic image rollover using jQuery, I've encountered an issue with the code below: HTML: <div class="secondcircle" id="circleone"> <p> <img src="/../ex/img/group1.png"> </p> </div> JS: $("# ...