【问题标题】:Do an update and after a delete进行更新并在删除后
【发布时间】:2020-07-06 16:04:53
【问题描述】:

我遇到了一个困扰我很久的问题。 我在 MariaBD 中有一个数据库(带有 WAMP),在 expressjs 中有一个 API。 在我的数据库中,我有两个表:表“menu”和表“item”,菜单上有外键。

我想对所有项目进行更新并将外键字段设置为空。 然后才删除菜单。

问题是更新完成得不够快,我的函数试图同时删除菜单(由于外键,这是不可能的)。

我尝试过使用 Promise 和 async/await,但它们都没有让我等待足够长的时间。

有什么想法吗?

我的代码没有异步/等待:

router.delete('/delete/:menuId', function (req, res, next) {
  return Item.findAll({
      where: {
        menuId: req.params.menuId,
      },
    })
    .then(
      itemsFounded => {
        //Unlink items / menu
        itemsFounded.forEach(element => {
          element.update({
            menuId: null
          })
        });
        //Then destroy menu
        Menu.destroy({
          where: {
            id: menuId
          }
        }).then(() => {
          return res / status(200);
        }).catch((err) => {
          console.log(err);
          return res.status(400);
        })
      }
    )
    .catch((error) => {
      console.log(error);
      res.status(400).send(error)
    });
});

我的 async/await 代码(对不起,如果它难以辨认,我不习惯):

router.delete('/delete/:menuId', async function (req, res, next) {
  return Item.findAll({
      where: {
        menuId: req.params.menuId,
      },
    })
    .then(
      async itemsFounded => {
        //Unlink items / menu
        const result = await getResult(itemsFounded, req.params.menuId);
        if (result === true) {
          console.log("result est true")
          return res.status(200);
        } else {
          console.log("result est false")
          return res.status(400).send("error");
        }
      }
    )
    .catch((error) => {
      console.log(error);
      res.status(400).send(error)
    });
});

async function getResult(itemsFounded, menuId) {
  console.log("In getResult");
  const result = await destroyMenu(itemsFounded, menuId);
  console.log("Result of destroyMenu : " + result);
  return result;
}

async function destroyMenu(itemsFounded, menuId) {
  console.log("Start destroyMenu");
  const result = await updateItems(itemsFounded);
  console.log("updateItems() : " + result);
  console.log("updateItems OK");
  Menu.destroy({
    where: {
      id: menuId
    }
  }).then(() => {
    console.log("In menu.destroy");
    return true;
  }).catch((err) => {
    console.log("Error in menu.destroy");
    console.log(err);
    return false;
  })
}

async function updateItems(itemsFounded) {
  console.log("in updateItems");
  itemsFounded.forEach(element => {
    element.update({
      menuId: null
    })
  });
  return true;
}

以及控制台的结果:

Executing (default): SELECT `id`, `name`, `description`, `picture`, `price`, `createdAt`, `updatedAt`, `menuId` FROM `items` AS `item` WHERE `item`.`menuId` = '1';
In getResult
Start destroyMenu
in updateItems
Executing (default): UPDATE `items` SET `menuId`=?,`updatedAt`=? WHERE `id` = ?
Executing (default): UPDATE `items` SET `menuId`=?,`updatedAt`=? WHERE `id` = ?
Executing (default): UPDATE `items` SET `menuId`=?,`updatedAt`=? WHERE `id` = ?
updateItems() : [object SequelizeInstance:item],[object SequelizeInstance:item],[object SequelizeInstance:item]
updateItems OK
Result of destroyMenu : undefined
result est false
DELETE /api/menu/delete/1 400 365.422 ms - 5
Executing (default): DELETE FROM `menus` WHERE `id` = '1'
In menu.destroy

【问题讨论】:

    标签: javascript node.js express asynchronous bdd


    【解决方案1】:

    您正在使用forEach-loop,并且在内部执行异步更新。您的代码的执行将在遍历循环后立即执行下一条语句,即它不会等待更新完成。

    您可以通过使用常规 for 循环和 async/await 来解决此问题:

    async function updateItems(itemsFound) {
      for(const foundItem of itemsFound) {
        await foundItem.update({
          menuId: null
        })
      });
    }
    

    如果您想并行而不是按顺序进行更新,另一种方法是使用Promise.all()

    async function updateItems(itemsFound) {
      return Promise.all(itemsFound.map(foundItem => foundItem.update({ menuId: null}) );
    }
    

    使用任一解决方案,您现在只需确保在调用它时等待 updateItems

    // ... find items
    await updateItems(...);
    // ... delete menu
    

    【讨论】:

    • 您好,感谢您的回答! Menu.destroy() 会出现同样的问题吗?查看日志,在请求结束后执行销毁(我更新了代码以显示 console.log):
    • 正在执行(默认):SELECT id, name, description, picture, price, createdAt, updatedAt, menuId FROM @98765@AS item 在哪里 item.menuId = '1';在 getResult Start destroyMenu in updateItems Executing (default): UPDATE items SET menuId=?,updatedAt=?在哪里id = ? updateItems() : [object SequelizeInstance:item],[object SequelizeInstance:item] updateItems OK 结果destroyMenu : undefined result est false DELETE /api/menu/delete/1 400 365.422 ms - 5 正在执行(默认):DELETE FROM @987654344 @ WHERE id = '1' 在 menu.destroy 中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    相关资源
    最近更新 更多