Don't initiate the next fetch until the previous one has completed

I am currently working on sending a list of data to Google Cloud. The code I have been using is as follows:

const teams = ['LFC', 'MUFC', 'CFC'];

teams.forEach(team => {
    fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
})

While this approach works with one team, it encounters timeouts when dealing with multiple larger files. I need to switch to POST the data one file at a time and ensure that each POST operation completes before moving onto the next one. How can I implement this in the most efficient way?

It's important to note that I do not have control over the number of files being uploaded.

Answer №1

Replace the use of forEach with a reduce, and include .then().

The code below will keep track of the promise from the last fetch in acc (the accumulator parameter of reduce). It appends the new fetch inside a then listener to ensure the previous fetch is completed:

const teams = ['LFC', 'MUFC', 'CFC'];

teams.reduce((acc, team) => {
  return acc.then(() => {
    return fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  })
}, Promise.resolve())
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))

//Simulate fetch:
const fetch = team => new Promise(rs => setTimeout(() => {rs();console.log(team)}, 1000))

const teams = ['LFC', 'MUFC', 'CFC'];

teams.reduce((acc, team) => {
  return acc.then(() => {
    return fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  })
}, Promise.resolve())
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))

You have the option to create a general helper function for this approach:

const teams = ['LFC', 'MUFC', 'CFC'];

const promiseSeries = (arr, cb) => arr.reduce((acc, elem) => acc.then(() => cb(elem)), Promise.resolve())

promiseSeries(teams, (team) => {
  return fetch({
    url: URL,
    method: 'PUT',
    body: team
  })
})
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))

//Simulate fetch:
const fetch = team => new Promise(rs => setTimeout(() => {rs();console.log(team)}, 1000))

const teams = ['LFC', 'MUFC', 'CFC'];

const promiseSeries = (arr, cb) => arr.reduce((acc, elem) => acc.then(() => cb(elem)), Promise.resolve())

promiseSeries(teams, (team) => {
  return fetch({
    url: URL,
    method: 'PUT',
    body: team
  })
})
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))

Alternatively, if you are able to (ES2017), utilizing async/await is recommended for improved readability:

const teams = ['LFC', 'MUFC', 'CFC'];

async function upload(teams){
  for(const team of teams){
      await fetch({
        url: URL,
        method: 'PUT',
        body: team
      });
  }
}

upload(teams)
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))

//Simulate fetch:
const fetch = team => new Promise(rs => setTimeout(() => {rs();console.log(team)}, 1000))

const teams = ['LFC', 'MUFC', 'CFC'];

async function upload(teams) {
    for (const team of teams) {
        await fetch({
          url: URL,
          method: 'PUT',
          body: team
        });
    }
}

upload(teams)
  .then(() => console.log("Everything's finished"))
  .catch(err => console.error("Something failed:", err))

Answer №2

Utilizing async/await alongside a for...of loop can help manage asynchronous calls more effectively. Each call will pause the loop execution until it's completed, allowing for better control over the sequence of actions:

const teams = ['LFC', 'MUFC', 'CFC'];

async function send(teams) {
  for (const team of teams) {
    await fetch({
      url: URL,
      method: 'PUT',
      body: team
    });
  }
}

Answer №3

One way to achieve this is by utilizing async/await in the code snippet below:

const players = ['Messi', 'Ronaldo', 'Neymar'];

players.forEach(async (player) => {
    await fetch({
      url: URL,
      method: 'POST',
      body: player
    });
})

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

Hide preloader in AngularJS once repeater has completed execution

Is there a way to hide a preloader div only after all data has finished loading in an ng-repeat loop? Check out this interactive example on Plunker: http://plnkr.co/edit/ilgOZzIy2axSi5Iy85C7?p=preview Here is the HTML code: <div ng-co ...

Tips for incorporating a multimedia HTML/JavaScript application within C++ programming

I possess the source code for a JavaScript/HTML5 application that operates on the client-side and manages the transmission/reception of audio and video data streams to/from a server. My objective is to develop a C++ application that fully integrates the c ...

I am getting a HTTP 405 error indicating that the method is not allowed, and it appears to

In my Javascript program, I requested this URL using the library epson-2.6.0.js, which is the Epson SDK for JavaScript specifically designed for thermal printers. My target device is a TM U220 connected via ethernet. GET XHR http://192.168.199.15:8008/soc ...

Why do I keep getting an ExpressionChangedAfterItHasBeenChecked error after trying to update a random color in an

Is there a way to assign a random color from an array without causing the error message: "ExpressionChangedAfterItHasBeenChecked"? Even though the color of the chip changes quickly before the message appears, it seems like it's working. How can I reso ...

How about representing a two-dimensional array in a point-free manner?

Exploring functional/tacit style programming, specifically implementing the snake game (example: ) The main issue at hand involves processing an array of strings like: [ ['2 '], ['10'] ] and obtaining a list of coordinates in numer ...

Developing a system mode called "night mode"

I've decided to incorporate a dark mode feature into my Wordpress theme. Creating both dark and light modes was a breeze, but now I want to add a third mode that serves as the default for pages. This new mode will automatically switch between dark a ...

Include a query parameter each time a page is added to bookmarks

Is there a way to automatically add a query parameter to a page URL when bookmarked using Chrome? For example, if I bookmark https://www.example.com, can it be saved as https://www.example.com/?bookmarked? I'm thinking I might need to use JavaScript ...

Error: Unable to locate module: Could not find '@/styles/globals.scss'

I'm encountering an error message with my import statement for the SCSS file in my _app.tsx. Can someone help me find a solution? I'm working with Next.js and have already exhausted almost every resource available online to fix this issue. ...

Tips for utilizing the GROUP BY Clause in Sequelize along with associations

How can I properly utilize the GROUP BY clause in Sequelize to combine data from two tables? This is the SQL query I am attempting to translate into Sequelize: SELECT products.product_name, SUM(order_list.quantity) FROM products JOIN order_list ON prod ...

Encountering a TypeError while attempting to sort in ReactJS: "0 is read only."

Every time I attempt to sort an object before mapping it in reactjs, I encounter the TypeError: 0 is read only. Despite trying to handle cases where props are empty or when the array length is more than 0 before applying the sort function, the error persis ...

What is the best way to link a file to index.html using feathers.js?

I am currently learning feathers and encountering a problem. I am attempting to include files similar to PHP's switch function. For instance: /src/middleware/index.js 'use strict'; const handler = require('feathers-errors/handler&ap ...

Retrieving information from Firebase after updating it

My goal is to automatically navigate to a specific ID after adding an item to my realtime database. Despite following the documentation's proposed solution, I am encountering issues with its implementation. Following the use of the push().set() meth ...

Issue with scroll animation across multiple div elements

I am working on a project where I have two main divs, one with the id of "left-div" and the other with the id of "right-div". In the "left-div", there are multiple nested divs each with their own unique id. The overflow-y property of the "left-div" is set ...

What's the reason behind the malfunction of this code on Chrome?

After recently installing Mobiscroll, I have been using the date scroller feature with the following code to manage the textbox. <script type="text/javascript"> $(function() { // create a datepicker with default settings $("#begi ...

How can Vue.js pass an array from a child component to its parent component?

I'm currently developing a contact book app and I have created a modal within a child component that contains a form with several input fields. My goal is to utilize the values entered in the form and add them to the parent component. I have successfu ...

Ajax - unable to show posts upon submission

Whenever I submit a post, I am unable to display them and I'm not sure why it's not working. The getPosts() function works fine when I refresh the page. However, after submitting the posts, I can't seem to retrieve them. I am using a JSON fa ...

The dictionary of parameters has an empty entry for the 'wantedids' parameter, which is of a non-nullable type 'System.Int32', in the 'System.Web.Mvc.JsonResult' method

The console is showing me an error stating that the parameters dictionary contains a null entry for parameter wantedids. I am trying to pass checked boxes to my controller using an array, so only the admin can check all boxes of tips for a specific user. T ...

Verify user identity before sending directory in Express

I'm encountering an issue with authenticating users before they access an express directory file tree. While I can successfully authenticate users on all other pages, I'm facing difficulties with authentication on "/dat/:file(*)" even though I ha ...

Implementing Ajax image upload functionality in Symfony2 framework

I am trying to implement a functionality where clicking on an image opens a window to select a new image and update the screen. However, when attempting to change the picture in the database, I encountered the following error: Catchable Fatal Error: Arg ...

Encountering issues with compiling files in react app using webpack, failing to compile as anticipated

When it comes to compiling, I prefer using webpack with TypeScript files. In my webpack.config.js file: module.exports = async (env, options) => { const dev = options.mode === "development"; const config = { //Webpack configuration pr ...