JavaScript中几种方法的异步执行顺序

JavaScript中几种方法的异步执行顺序,javascript,Javascript,我在JavaScript NodeJS Sequelize中有一个三个方法。 调用它们保存如下: setTransferHistory(senderId, recipientId, amountMoney, transferTitle); setWidgetStatus(senderId); setWidgetStatus(recipientId); 每个方法都会在mysql数据库中进行更新或选择。 这是非常重要的,他们是在这个顺序,并不总是这样 我知道解决这个问题在setTransferHi

我在JavaScript NodeJS Sequelize中有一个三个方法。 调用它们保存如下:

setTransferHistory(senderId, recipientId, amountMoney, transferTitle);
setWidgetStatus(senderId);
setWidgetStatus(recipientId);
每个方法都会在mysql数据库中进行更新或选择。 这是非常重要的,他们是在这个顺序,并不总是这样

我知道解决这个问题在setTransferHistory方法中使用单词then,因此:

  function setTransferHistory(
    senderId,
    recipientId,
    amountMoney,
    transferTitle,
  ) {
    Transaction.create({
      id_sender: senderId,
      id_recipient: recipientId,
      date_time: getTodayDate(),
      amount_money: amountMoney,
      transfer_title: transferTitle,
    }).then(() => {
      setWidgetStatus(senderId);
      setWidgetStatus(recipientId);
    });
  }

…但是我不想在这个方法中包括这两种方法。我只想一个接一个地写。

您所需要做的就是
返回
来自
setTransferHistory
create
给您的承诺,以便您可以调用
然后根据调用结果调用

function setTransferHistory(senderId, recipientId, amountMoney, transferTitle) {
  return Transaction.create({
//^^^^^^
    id_sender: senderId,
    id_recipient: recipientId,
    date_time: getTodayDate(),
    amount_money: amountMoney,
    transfer_title: transferTitle,
  });
}


现在在处理承诺时,好的做法是使用async/await关键字。它们基本上允许您以同步方式运行异步代码。使用它们,您的代码将如下所示:

async function setTransferHistory(senderId, recipientId, amountMoney, transferTitle) {
     return await Transaction.create({
       id_sender: senderId,
       id_recipient: recipientId,
       date_time: getTodayDate(),
       amount_money: amountMoney,
       transfer_title: transferTitle,
     });
}

await setTransferHistory(senderId, recipientId, amountMoney, transferTitle);
setWidgetStatus(senderId);
setWidgetStatus(recipientId);
await关键字停止函数的执行并等待事务的结果。需要create()和async才能在函数中使用await


希望这有帮助。

因为
事务。create
返回一个
承诺
,您可以让
setTransferHistory
返回该承诺,并在
setTransferHistory
的承诺履行后推迟执行
setWidgetStatus
。因此:

const setTransferHistory = (
  senderId,
  recipientId,
  amountMoney,
  transferTitle
) =>
  Transaction.create({
    id_sender: senderId,
    id_recipient: recipientId,
    date_time: getTodayDate(),
    amount_money: amountMoney,
    transfer_title: transferTitle
  });
您可以选择:

setTransferHistory(/* args ... */).then(() => {
  setWidgetSatus(senderId);
  setWidgetSatus(recipientId);
});
或者使用
await
-这与promise一起工作,只要在
async
函数中使用它,
setTransferHistory
就不需要是异步的:

async function foobar() {
  await setTransferHistory(/* args ... */);

  setWidgetSatus(senderId);
  setWidgetSatus(recipientId);
}

当然,在这一点上,您可以直接使用
transaction.create
,但如果您想添加抽象层,这取决于您自己。

您现在的问题是什么?您可以使用wait/async语法,但这只是对相同承诺的补充。如果您想保证顺序,您需要链接异步调用,以便只有在前一个解析后才能进行下一个调用。同时调用两个是错误的,因为第二个可以在第一个之前很好地解决。虽然在这种情况下可能没有错,使用
async/await
而不是直接操纵承诺通常是一个坏主意:您不能与
async/await
同时进行异步操作。不,您完全正确,但我能想到的最简单的方法是不必使用
then()
并按所需顺序调用函数。
return wait
绝对不是一个好做法。实际上没有必要将
setTransferHistory
设置为
async
函数。您能详细说明一下吗?我知道没有绝对必要这样做,他可以按照您的建议返回
Transaction.create()
,然后使用
then()
函数,但由于他明确表示不希望“此方法中包含这两种方法”,我认为使用
async/await
是一个很好的解决方案。
async function foobar() {
  await setTransferHistory(/* args ... */);

  setWidgetSatus(senderId);
  setWidgetSatus(recipientId);
}