【问题标题】:Promises in array forEach loop数组 forEach 循环中的 Promise
【发布时间】:2021-01-19 09:54:35
【问题描述】:

我有一个这样的数组:

var ids = [8372839402, 8392615782, 3677281302];

插入的是 id 值。基于这个 id,我必须从数据库中为每个人获取一些信息。 基本上我通过使用位于 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);
  });
}      

在我的 main.js 中,我基本上是这样使用这个函数的:

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
        }
      });     

但是当我在数组中使用它时,它就不起作用了。从我开始,我对 var currentpromise 有多个承诺,或者通过每次在数组 forEach 中调用 getdata 函数来覆盖它们。
如何解决我的问题以无错误地循环遍历数组?

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
             }
           });  
        }
      });  
});    

我不认为这很重要,但这里我们有 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);
?>    

编辑: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;
    }
  }
}

希望有人可以帮助我。提前致谢。
菲利普

【问题讨论】:

  • getdata() 没有返回任何内容,您希望obj 是什么?
  • 不要覆盖外部变量,只需让get_data 返回创建的承诺。然后在你的循环中使用它:get_data(...).then(function (reply) { ... }); 或者更好的是,使用.map 将 id 数组转换为 promise 数组,然后将其传递给 Promise.all(...)
  • 这是一个很容易发生 sql 注入的代码示例。当有人调用getData('DROP DATABASE') 时,人头就会滚动。
  • @ChrisG 你能写一个简短的答案吗?
  • 只需将 id 作为 arg 传递给 getData() 函数(而不是 sql 命令)将是一个好的开始。使用 PDO 构建查询也很好。

标签: javascript php arrays foreach promise


【解决方案1】:

ForEach本质上是同步的,你不应该在forEach循环中使用promise或任何异步代码,因为它会简单地遍历数组而不等待promise得到实现。 您可以改用for await...of 循环。

【讨论】:

    猜你喜欢
    • 2020-11-13
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多