how to perform the function asynchronously? (edited)

Viewed 88

UPD: How do I perform the encode function in my code asynchronously? the problem is that encode with a lot of data takes a long time, i would like to encode asynchronously and then add everything to the response array and return to the user

code

var total = records.length
var data = []
var response = []
for(var i = 0; i < total; i++){
      data.push(records[i])
      response.push([
        records[i].userId,
        global.encode(data)
      ]);
  }

old question ( I was in a hurry and wrote the wrong question ) How to make the array appending asynchronously? The problem is that during an iteration of the array i add new data to it and in the same iteration i need to encode it, with each iteration cycle it takes more and more time question how can i encode and add to the array asynchronously in a synchronous function? here is a code example (not working):

app.post('/encodeSomeData', cors(), (req, res) => {
  var i = 0
  var response = [];
  var records = req.body.data
  var data = []
  async function lol(){
      await encode(i)
      i++;
      if(i == records.length && response.length == records.length){
        res.send({
          success: true,
          result: response
        })
      }else{
        await lol();
      }
  }

  async function processMyArray (array, index) {
    array[1] = global.encode(array[1])
    response[index] = array
  }

  async function encode(j){
      console.log(j);
      data.push(records[j])
      await processMyArray([
        records[j].userId,
        data
      ], j)
  }
  lol();
});
3 Answers

I would use rxjs to set up an asychronous data pipe.

import {scheduled, asyncScheduler} from 'rxjs';
import {scan, map} from 'rxjs/operators';

function 
scheduled(
  records, // emit each record...
  asyncScheduler // ... asynchronously
).pipe(
  scan( // combine previously emitted and the current record, kind of like array.accumulate except it also emits each step
    (acc, r) => [
      r.userId,
      acc[1].push(r)
    ],
    [null, []] // this is the seed (the first acc)
  ), // at this point we have what we want except the second element isn't encoded, so...
  map(
    a => [a[0], global.encode(a[1])]
  )
).subscribe({ // without subscribe, we just have chained operations but haven't actually executed anything yet! Subcribe is what starts the flow.
  next: a => response.push(a)
})

Once debugged, this should asynchronously push values into response.

Why you would need or want to repeatedly encode records[0] a total of records.length times is beyond me but that wasn't part of your question.

You can map array to Array<Promise> , and use Promise.all

like this

const addOneAsync = (i) =>
  new Promise((resolve) =>
    setTimeout(() => resolve(i + 1), Math.random() * 1000)
  );

const data = [0, 1, 2, 3, 4, 5];

const result = data.map(addOneAsync);

console.log(result.toString()); //Array<Promise>

Promise.all(result).then(console.log);

In your case like this

const records = [{ userId: 1 }, { userId: 2 }, { userId: 3 }, { userId: 4 }, { userId: 5 }];

const encode = (arr) => new Promise((resolve) => setTimeout(() => resolve(JSON.stringify(arr)), Math.random() * 1000));

const data = [];
const result = records.map(async (record) => {
  data.push(record);
  return [record.userId, await encode(data.concat())];
});

Promise.all(result).then(console.log);

Try this

const encode = (data) => new Promise((resolve) => setTimeout(() => resolve(global.encode(data)), 0));

app.post('/encodeSomeData', cors(), (req, res) => {
  const records = req.body.data;
  const data = [];
  const result = records.map(async (record) => {
    data.push(record);
    return [record.userId, await encode(data.concat())];
  });

  Promise.all(result).then((response) => res.send({ success: true, result: response }));
}

If your goal is to run multiple Array.push() instances simultaneously, this could work:

async function push(data, array) {
  array.push(data)
}

Appending data is inherently synchronous, but a library like Bacon might be of use

Related