Promises in array forEach loop

Tags: , , , ,



I have an array like this:

var ids = [8372839402, 8392615782, 3677281302];

Inserted are id values. Based on this ids I have to get for each one some information from the database. Basicly I get data by using following function which is located in db.js:

function getdata(get_command) {
  var request = new XMLHttpRequest();
  var params = params + 'command=' + encodeURIComponent(get_command) + '&';

  console.log(params);

  currentpromise = new Promise(function(resolve, reject) {
    request.open('POST', './php/get_data.php', true);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.onreadystatechange = function() {
      if (request.readyState === XMLHttpRequest.DONE) {
        if (request.status === 200) {
          var response = JSON.parse(request.response);
          resolve(response);
        }
        else {
          resolve({error: 'Cant connect!'});
        }
      }
    };
    request.send(params);
  });
}      

And than bascily in my main.js I use this function like this:

var user_id = 'r82h9hfew89hf9983f8d9';
var currentpromise;
var obj = getdata('SELECT username, email FROM users WHERE id=' + user_id);
      currentpromise.then(function(obj) {
        if (obj.data[0] == 'false') {

        }
        else {
           //succesfully go on
        }
      });     

But when I would use this in an array it wouldnt work. Beginning with that I have multiple promises on the var currentpromise or that they get override by calling the getdata function every time in array forEach.
How to fix my problem to loop through the array without errors?

ids.forEach(function(id) {
    var obj = getdata('SELECT name FROM data WHERE id=' + id);
      currentpromise.then(function(obj) {
        if (obj.data[0] == 'false') {

        }
        else {
           //succesfully do next step
           var obj = getdata('SELECT version FROM vers WHERE name=' + obj.data[0]['name']);
           currentpromise.then(function(obj) {
             if (obj.data[0] == 'false') {

             }
             else {
               //succesfully finished with one id
             }
           });  
        }
      });  
});    

I dont think it is so important but here we have the get_data.php:

<?php
include('classes/db.php');

$data = array();
$command = urldecode($_POST['command']);

$result_value = db::query($command);
$data['data'] = $result_value;

// return all our data to an AJAX call
echo json_encode($data, JSON_PRETTY_PRINT);
?>    

EDIT: dp.php

<?php

class db {
  private static function connect() {
    //db inf, username, pwd
    $pdo = new PDO('mysql:host=127.0.0.1;dbname=emergencybase;charset=utf8', 'root', '');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $pdo;
  }

  public static function query($query, $params = array()) {
    $statement = self::connect()->prepare($query);
    $statement->execute($params);

    if (explode(' ', $query)[0] == 'SELECT') {
      $data = $statement->fetchAll();
      return $data;
    }
  }
}

Hope someone can help me with this. Thanks in advance.
Filip

Answer

ForEach is synchronous in nature and you shouldn’t use promises or any async code inside forEach loop as it will simply iterate over array without waiting for promise to get fulfilled. You could for await...of loop instead.



Source: stackoverflow