Different ways to repeatedly call a function returning a promise in synchronous fashion

For instance, I have a function that uses Promise.resolve() to return a cached entity id if available, but if not, it makes an ajax call to reserve a new entity id and then returns the newly reserved id.

function getReservedEntityId(collectionName) {
        //if (!haveCachedIds) {
            //make ajax call to reserve new ids
            Promise.resolve(newId);
        }
        return Promise.resolve(cachedId);
};

How can we efficiently call this function multiple times to reserve multiple entity ids?

P.S. I am aware that the correct approach is to pass a parameter specifying the count of entity ids to reserve, but I am curious about synchronously calling a function multiple times that returns promises.

Answer №1

To properly implement getReservedEntityId(), it is crucial to understand how promises work. I recommend thoroughly reading through the documentation on promises. When dealing with asynchronous tasks in your function, you must ensure that a promise is returned which will either resolve or reject based on the outcome of the asynchronous operation.

function getReservedEntityId(collectionName) {
  if (haveCachedIds) {
    return Promise.resolve(cachedId);
  } else {
    return new Promise((resolve, reject) => {
      // Perform AJAX call and use resolve(newId) in success callback
      // or reject(errCode) in failure callback.
      // The `newId` and `errCode` can be any values and are passed 
      // to the next chain link in the promise like then() or catch()
    });
  }
}

After ensuring this aspect is taken care of, there are two recommended methods to handle synchronous calls:

1) Using a promise chain

getReservedEntityId(collectionName)
  .then((id) => {
    // Process `id` first...
    
    return getReservedEntityId(collectionName);
  })
  .then( ... )
  .then( ... );

If you plan to pass the same function to each `.then()` call, consider declaring it as a regular function to avoid redundancy.

2) Employing async/await

This ES2017 feature is not widely supported yet. While Node.js supports async/await with the `--harmony` flag, most browsers do not. Despite this, async/await streamlines handling functions returning promises as if they were synchronous. To incorporate async/await now, transpile your JavaScript using tools that make it compatible with all major browsers.

Here's an example of utilizing async/await:

(async function someAsyncFunction {
  const id1 = await getReservedEntityId(collectionName);
  const id2 = await getReservedEntityId(collectionName);
  const id3 = await getReservedEntityId(collectionName);
                          .
                          .
                          .
})();

The syntax of async/await enhances readability compared to promise chains as it caters to such scenarios. Note that I've implemented a self-invoking function here to align with your approach without needing an additional function call. You can use and invoke a function defined with `async function` similar to any other promise-returning function.

Answer №2

Hey @fvgs, your answer is spot on as well! I wanted to share the complete solution with you and discuss the challenge I encountered while maintaining a list of reserveIds received from each getReservedEntityId call.

fetchEntityIds: function (entity, quantity) {
    if (!quantity || quantity == 1)
        return Utility.getReservedEntityId(entity);

    var promise = new Promise(function(resolve, reject) {
        var results = [];
        var chain = Utility.getReservedEntityId(entity);
        var callback = function Cb(results, newId) {
            results.push(newId);

            if (results.length === quantity)
                resolve(results);
            else
                return Utility.getReservedEntityId(entity);
        }.bind(null, results);

        for (var i=1; i <= quantity; i++) {
            chain.then(callback);
        }

        chain.catch(reject);
    });

    return promise;
}

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

When hovering over an image to show a text box using JavaScript, it only works on one image due to the use of getElementById

I have been experimenting with some JavaScript code to create a pop-up box that appears when you hover over images. However, I have encountered an issue where it only works for one image. I suspect this is because I have used IDs instead of classes, but I& ...

Is there a way in JQuery to apply the CSS of one element to another selected element?

I'm curious if there is a JQuery function available that can be used to transfer the exact CSS styles from one element to another. I want all the CSS properties to be applied without any additional inheritance. For example: <div id="d1"> &l ...

Utilizing vanilla JavaScript or ES6 to extract data from a JSON file

I am currently working on an HTML project where I need to extract data from a JSON file that cannot be modified. I am looking to accomplish this using pure JavaScript or ES6, but I am struggling to make it work. Specifically, I am trying to retrieve a link ...

Connecting prop variables to component variables establishes a direct relationship between them

By assigning the props variable to a component variable, any changes made to the component variable will also reflect in the props... Parent Component: const prova = [ { 1: 'a' }, { 2: 'b' }, { ...

The @emit event in vue.js is not being received by the parent component

Within my application, there is a form located in the ManageCards component. This form includes a child component called ImageUpload, which emits an image file and its local URL to the parent component: <form class="mb-3"> <div class ...

The issue causing "ReferenceError: fetch is not defined" is causing the test to fail

There seems to be an issue with my project where 'node-fetch' is installed, but the rest of the files are not importing it and the tests are not failing import { IQuery } from 'models/IQuery.interface'; import { NextApiRequest, NextApiR ...

Error: [BITFIELD_INVALID_RANGE]: The bitfield flag or number entered is not valid: 3214336

Currently working on a Discord Dashboard project, but encountering an unusual error: Invalid bitfield flag or number 3214336. This issue arises when attempting to retrieve the guilds that a user has MANAGE_GUILDS permission for. Below is the snippet of my ...

Is it possible to spread an empty array in JavaScript?

Whenever I run the code below, I encounter the error message Uncaught SyntaxError: expected expression, got '...': [1,2,3, (true ? 4 : ...[])] I'm wondering if spreading an empty array in that manner is allowed? ...

Discover how to use jQuery to locate and substitute a class of an element

I'm currently facing a limitation on the platform I'm using, as it restricts me from making HTML changes. To work around this constraint, I have to utilize JQuery to locate and swap one div with another (or in simpler terms, find specific text in ...

Exploring how to integrate a jQuery ajax request within Javascript's XmlHttpRequest technique

My current setup involves an ajax call structured like this: var data = {"name":"John Doe"} $.ajax({ dataType : "jsonp", contentType: "application/json; charset=utf-8", data : JSON.stringify(data), success : function(result) { alert(result.success); // re ...

Javascript Steps to trigger a function when selecting the Stay on Page option in Google Chrome

If you're testing my code in the Chrome Browser, hitting refresh will prompt you with 2 options. Leave This Page Stay on This Page By clicking on the Stay on this page button, it should trigger my custom function displayMsg(). Can anyone pr ...

Is it considered poor form to use res.locals in Node.js with Express?

Is it considered bad practice to use res.locals as shown in this code example? Are there potential issues that could arise from using it in this manner? app.use((req, res, next) => { const session = req.cookies.session if (session) { db. ...

The onclick functionality is not functioning properly within email communications

My JavaScript code contains an AJAX call within Datatables, and this snippet of code is causing an issue: { "data": null, "width": "10%", "render": function(data){ icon2 = '<center><button type="button" class="btn btn-info ...

Exploring the challenges of implementing the Lob Node API wrapper within a MeteorJs project due to conflicts with the 'fs' module

I recently updated to the latest version of Meteor (1.13) which now supports NPM. I decided to add the Lob.com NPM to my project and started working on a letter function. However, I encountered the following error: Uncaught TypeError: fs.readdirSync is ...

Send the id from the controller to the script following a Post request

In continuation from the previous question Original question I am currently facing an issue with passing an Id to a link (e.g. http://localhost:1914/en/Events/Index/22). I was advised to pass it via JSON results, but I am unable to retrieve it back in my ...

Sharing data between two components on the same level in Vue.js

I have a situation where I need to transfer data from one component1 to another component2. I am not utilizing vuex or router for this task. The component tree looks like this: -Parent --Component1 --Component2 In the first component1, I am sending an ...

The data retrieved from the Youtube API is not being saved in the useState variable

Having an issue with the YouTube API integration in my React app. The fetched data isn't being stored correctly in the useState variable, causing my VideoCard component not to render. How can I fix this and ensure the data is stored properly? import R ...

React: Submit button not triggering form submission despite having a valid submit event handler and correct syntax

My question stands out from existing ones as it features valid syntax, correct use of type="submit" on the button, and a simple onSubmit handler on the form. Despite this, clicking the button fails to trigger the onSubmit handler. To illustrate ...

Encountering unidentified data leading to the error message "Query data must be defined"

Currently, I'm utilizing Next.js to develop a project for my portfolio. In order to manage the API, I decided to implement both Tanstack query and Axios. The issue arises when attempting to retrieve the data as an error surfaces. Oddly enough, while ...

Using jquery to loop through JSON objects based on their values

Looking to display the NBA Western Conference leaders by seed, I have utilized the JSON file available at: http://data.nba.com/data/v2014/json/mobile_teams/nba/2014/00_standings.json Here is the current setup: $(document).ready(function() { $.getJSON( ...