An array of Promises passing variables used during creation

Using Express, I use .map to create an array of API calls, the results of which I want to combine into a single response object. Since each call uses different request parameters, I would like to use the request parameters as keys of the response object.

I create GET requests using axios, which returns a promise, and then I use axios.all to wait for all promises to resolve.

The problem is that after resolving promises, I no longer have access to the variables used to create them. How can I attach these variables to promises for a later reference?

Here is the API:

router.get('/api', (req, res) => {
  const number = req.query.number;
  res.json({ content: "Result for " + number });
});

This is where I am trying to combine the results:

router.get('/array', async (req, res) => {
  res.locals.payload = {};
  const arr = [1, 2, 3, 4, 5];
  const promises = arr.map(number => {
    return axiosInstance.get('/api', { params: { number: number } })
  });
  const results = await axios.all(promises);
  results.map(r => {
    // number should match original, but I no longer have
    // access to the original variable
    number = 1;
    res.locals.payload[number] = r.data;
  });
  res.json(res.locals.payload);
});

GET on / array result:

{
    "1": {
        "content": "Result for 5"
    }
}

What should I do when creating Promise objects to save keys?

+4
1

0 "1", "2" .., Promise.all ( axios.all, Promise.all , , , promises, , ). , "" - .: -)

, , - , .

get :

const promises = arr.map(number => {
  return axiosInstance.get('/api', { params: { number } })
         .then(result => ({result, number}));
});

results all.then result number. , results.map, :

//           vvvvvvvvvvvvvvvv---------------- destructuring parameters
results.map(({result, number}) => {
  res.locals.payload[number] = result.data;
//                   ^^^^^^----^^^^^^-------- using them
});

:

// Fake axiosInstance
const axiosInstance = {
    get(url, options) {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve({data: `Data for #${options.params.number}`});
            }, 300 + Math.floor(Math.random() * 500));
        });
    }
};
// Fake axios.all:
const axios = {
    all: Promise.all.bind(Promise)
};

// Fake router.get callback:
async function routerGet() {
    const payload = {}; // stand-in for res.locals.payload
    const arr = [1, 2, 3, 4, 5];
    const promises = arr.map(
      number => axiosInstance.get('/api', { params: { number } })
                             .then(result => ({result, number}))
    );
    const results = await axios.all(promises);
    results.map(({result, number}) => {
      /*res.locals.*/payload[number] = result.data;
    });
    console.log(/*res.locals.*/payload);
}

// Test it
routerGet().catch(e => { console.error(e); });
Hide result

. ES2015 + , .. { number } , { number: number }.


2: map, :

const promises = arr.map(
  number => axiosInstance.get('/api', { params: { number } })
                         .then(result => ({result, number}))
);
0

Source: https://habr.com/ru/post/1683901/


All Articles