首页 > 解决方案 > Javascript:启动两个连续等待会产生错误的结果

问题描述

async function getHistoriqueDesOperatiosnSav(callback) {
  operationSavsHistorique = await models.journal_operation_sav.findAll({
    order: [["id", "ASC"]]
  });
  const resObj = operationSavsHistorique.map(
    async operationSavHistoriqueEntry => {
      const mapStatusToDisplayedValue = {
        produit_recu: "Produit reçu",
        en_livraison: "En livraison",
        en_reparation: "En cours de réparation",
        repare: "Réparé",
        en_expedition: "Envoyé au client",
        expedie: "Reçu par le client",
        annule: "Annulé"
      };

      operationSav = await operationSavHistoriqueEntry.getOperation_sav();
      admin = await operationSavHistoriqueEntry.getAdmin();

      logger.error(
        "retrieved operationSav by using Async is",
        operationSav.nom_operation
      );
      logger.error("retrieved admin by using Async is", admin.nom);

      return Object.assign({
        id: operationSavHistoriqueEntry.id,
        nom_operation: operationSav.nom_operation,
        admin: admin.nom,
        status: mapStatusToDisplayedValue[operationSavHistoriqueEntry.status]
      });
    }
  );
  const operationSavToDisplay = await Promise.all(resObj);
  callback(operationSavToDisplay);
}

该函数给出了以下结果:

[


       {
        "id": 1,
        "nom_operation": "TestRefresh",
        "admin": "Administrateur Ghrib",
        "status": "Réparé"
    },
    {
        "id": 2,
        "nom_operation": "TestRefresh",
        "admin": "Administrateur Ghrib",
        "status": "En livraison"
    },
    {
        "id": 3,
        "nom_operation": "TestRefresh",
        "admin": "Administrateur Ghrib",
        "status": "En livraison"
    },
    {
        "id": 4,
        "nom_operation": "TestRefresh",
        "admin": "TechnicienTestOperationSav",
        "status": "En cours de réparation"
    },
    {
        "id": 5,
        "nom_operation": "TestRefresh",
        "admin": "TechnicienTestOperationSav",
        "status": "Réparé"
    },
    {
        "id": 6,
        "nom_operation": "TestRefresh",
        "admin": "TechnicienTestOperationSav",
        "status": "En cours de réparation"
    },
    {
        "id": 7,
        "nom_operation": "TestRefresh",
        "admin": "TechnicienTestOperationSav",
        "status": "Réparé"
    },
    {
        "id": 8,
        "nom_operation": "TestRefresh",
        "admin": "Administrateur Ghrib",
        "status": "En livraison"
    },
    {
        "id": 9,
        "nom_operation": "TestRefresh",
        "admin": "Administrateur Ghrib",
        "status": "En livraison"
    },
    {
        "id": 10,
        "nom_operation": "TestRefresh",
        "admin": "TechnicienTestOperationSav",
        "status": "En cours de réparation"
    },
    {
        "id": 11,
        "nom_operation": "TestRefresh",
        "admin": "TechnicienTestOperationSav",
        "status": "En cours de réparation"
    },
    {
        "id": 12,
        "nom_operation": "TestRefresh",
        "admin": "TechnicienTestOperationSav",
        "status": "Réparé"
    },
    {
        "id": 13,
        "nom_operation": "TestRefresh",
        "admin": "Administrateur Ghrib",
        "status": "Envoyé au client"
    }
]

问题:属性nom_operation始终相同。在数据库中,它是不同的。
这显然是我实现两个await的问题:

 operationSav = await operationSavHistoriqueEntry.getOperation_sav();
          admin = await operationSavHistoriqueEntry.getAdmin();

我试图像这样修复它:

async function getHistoriqueDesOperatiosnSav(callback) {
  operationSavsHistorique = await models.journal_operation_sav.findAll({
    order: [["id", "ASC"]]
  });
  const resObj = operationSavsHistorique.map(
    async operationSavHistoriqueEntry => {
      const mapStatusToDisplayedValue = {
        produit_recu: "Produit reçu",
        en_livraison: "En livraison",
        en_reparation: "En cours de réparation",
        repare: "Réparé",
        en_expedition: "Envoyé au client",
        expedie: "Reçu par le client",
        annule: "Annulé"
      };

      // Begin first call and store promise without waiting
      const someResult = operationSavHistoriqueEntry.getOperation_sav();

      // Begin second call and store promise without waiting
      const anotherResult = operationSavHistoriqueEntry.getAdmin();

      // Now we await for both results, whose async processes have already been started
      const [admin, operationSav] = [await someResult, await anotherResult];
      // At this point all calls have been resolved
      // Now when accessing someResult| anotherResult,
      // you will have a value instead of a promise
      return Object.assign({
        id: operationSavHistoriqueEntry.id,
        nom_operation: operationSav.nom_operation,
        admin: admin.nom,
        status: mapStatusToDisplayedValue[operationSavHistoriqueEntry.status]
      });
    }
  );
  const operationSavToDisplay = await Promise.all(resObj);
  callback(operationSavToDisplay);
}

这是结果

[
  {
    id: 1,
    nom_operation: undefined,
    admin: undefined,
    status: 'Réparé'
  },
  {
    id: 2,
    nom_operation: undefined,
    admin: undefined,
    status: 'En livraison'
  },
  {
    id: 3,
    nom_operation: undefined,
    admin: undefined,
    status: 'En livraison'
  },
  {
    id: 4,
    nom_operation: undefined,
    admin: undefined,
    status: 'En cours de réparation'
  },
  {
    id: 5,
    nom_operation: undefined,
    admin: undefined,
    status: 'Réparé'
  },
  {
    id: 6,
    nom_operation: undefined,
    admin: undefined,
    status: 'En cours de réparation'
  },
  {
    id: 7,
    nom_operation: undefined,
    admin: undefined,
    status: 'Réparé'
  },
  {
    id: 8,
    nom_operation: undefined,
    admin: undefined,
    status: 'En livraison'
  },
  {
    id: 9,
    nom_operation: undefined,
    admin: undefined,
    status: 'En livraison'
  },
  {
    id: 10,
    nom_operation: undefined,
    admin: undefined,
    status: 'En cours de réparation'
  },
  {
    id: 11,
    nom_operation: undefined,
    admin: undefined,
    status: 'En cours de réparation'
  },
  {
    id: 12,
    nom_operation: undefined,
    admin: undefined,
    status: 'Réparé'
  },
  {
    id: 13,
    nom_operation: undefined,
    admin: undefined,
    status: 'Envoyé au client'
  }
]

问题1:为什么在第一个场景中,nom_operation属性总是一样的?
问题2:为什么字段nom_operationadminundefined在第二种情况下?
问题3:我应该如何解决这个问题?


编辑1:我稍微修改了函数:

即使它记录了正确的operationSav数据admin。换句话说,它从数据库中 检索正确的结果。

2020-03-06T15:22:54+0100 <info> OperationSavServices.js:393  result[1] is: 
{
  id: 76,
  nom: 'TechnicienTestOperationSav',
  email: 'TechnicienTestOperationSav@gmail.com',
  mot_de_passe: 'U2FsdGVkX18zRDQHQaiOCs1Jpk4Lv8JHPpvfTkWWNpY=',
  last_login: null,
  role: 'operateur_sav',
  createdAt: 2020-03-04T13:21:13.595Z,
  updatedAt: 2020-03-04T13:21:13.595Z
}
2020-03-06T15:22:54+0100 <info> OperationSavServices.js:391  result[0] is: 
{
  id: 28,
  nom_operation: 'OperationTestRefresh999',
  num_serie: 'OperationTestRefresh999',
  address_mac: 'OperationTestRefresh999',
  sous_garantie: false,
  description: 'OperationTestRefresh999',
  adminId: 8,
  produitId: 2,
  status: 'repare',
  nomClient: 'OperationTestRefresh999',
  createdAt: 2020-03-04T14:49:27.977Z,
  updatedAt: 2020-03-06T09:56:25.014Z
}
2020-03-06T15:22:54+0100 <info> OperationSavServices.js:393  result[1] is: 
{
  id: 76,
  nom: 'TechnicienTestOperationSav',
  email: 'TechnicienTestOperationSav@gmail.com',
  mot_de_passe: 'U2FsdGVkX18zRDQHQaiOCs1Jpk4Lv8JHPpvfTkWWNpY=',
  last_login: null,
  role: 'operateur_sav',
  createdAt: 2020-03-04T13:21:13.595Z,
  updatedAt: 2020-03-04T13:21:13.595Z
}

最终结果还是和场景二一样!

标签: javascriptasynchronouspromiseasync-awaitsequelize.js

解决方案


推荐阅读