【问题标题】:javascript async await I don't understand how it worksjavascript async await 我不明白它是如何工作的
【发布时间】:2021-07-15 23:57:20
【问题描述】:

您好,我正在更深入地研究 Javascript async/await,但我有一些我不理解的代码。

在这段代码中,我首先将一个数组 [1,2,3,4] 发送到一个名为 timeCall 的函数,然后再次将它与 [5,6,7,8] 一起发送。所以,我希望代码工作的方式是

1 2 3 4
h e l l o
5 6 7 8
h e l l o

是啊,为什么

1 5
h e l l o
2 6
h e l l o 

我不确定这是否是这样处理的。如果我使用map而不是for of语句,1到8完成后,hello重复出现。我想现在,当我遇到等待时,我继续进行微任务并发送下面的 5 6 7 8。我觉得没什么问题

1 2 3 4 你好 5 6 7 8 ....

如何修改代码以输出这样的数据?

const timeArrs = [
  'h',
  'e',
  'l',
  'l',
  'o'
]

function time(arr) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(arr));
    }, 3000);
  })
}

function timeArrProcessing(arr) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(arr));
    }, 2000);
  })
}

function hi() {
  return Promise.all(timeArrs.map(async(arr) => {
    await timeArrProcessing(arr);
  }));
}

async function timeCall(arrs) {
  for(const arr of arrs) {
    await time(arr);
    await hi();
  }
  console.log('End');
}

timeCall([1, 2, 3, 4]);
timeCall([5, 6, 7, 8]);

【问题讨论】:

  • timeCall 调用中没有 await,这就是它们“并行”运行的原因
  • @GuerricP,timeCall 在顶层。考虑timeCall([1, 2, 3, 4]).then(() => timeCall([5, 6, 7, 8]));
  • 然后用then链接它们或将它们封装在async IIFE中
  • 除了不等待timeCall 的主要问题之外,这段代码令人困惑。 timeArrs.map(async(arr) => ... arr 不是一个数组,而是一个字符。变量的名称不是很有启发性。您的代码输出“结束”,这不在您想要的输出中。 hi() 在每个数组元素输出后被调用,但你不希望这样......

标签: javascript async-await es6-promise


【解决方案1】:

正如 cmets 中提到的,您的代码中有几个问题...首先,只需调用一个异步函数将立即启动它“在后台”运行,并且不会阻塞其他代码,所以这些行正在启动两个同时运行的 timeCall 实例

timeCall([1, 2, 3, 4]);
timeCall([5, 6, 7, 8]);

如果您希望第一个在运行第二个之前完成,则需要等待它。但由于 await 仅适用于异步函数,您可能需要 async iife 来运行它们

(async()=>{
  await timeCall([1, 2, 3, 4]);
  await timeCall([5, 6, 7, 8]);
})()

您还在每个元素完成后添加了 hi 函数,而不是在它们全部完成后,因此您可能希望将 timeCall 更改为:

async function timeCall(arr) {
  for(const elem of arr) {
    await time(elem);
  }
  await hi();
}

另外 - 看起来您可能希望 hi 在 'hello' 中的字母之间暂停?如果是这样,您将需要这样的东西:

async function hi() {
  for(const elem of timeArrs) {
    await timeArrProcessing(elem);
  }
}

所以,把所有这些放在一起,试试下面的,看看它是否适合你:

const timeArrs = [
  'h',
  'e',
  'l',
  'l',
  'o'
];

(async()=>{
  await timeCall([1, 2, 3, 4]);
  await timeCall([5, 6, 7, 8]);
  console.log('End');
})()

async function timeCall(arr) {
  for(const elem of arr) {
    await time(elem);
  }
  await hi();
}

function time(elem) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(elem));
    }, 3000);
  })
}

function timeArrProcessing(arr) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(arr));
    }, 2000);
  })
}

async function hi() {
  for(const elem of timeArrs) {
    await timeArrProcessing(elem);
  }
}

【讨论】:

  • 感谢你,我很好的理解了这个问题,改进了项目的代码,对异步控制有了更好的感受。
猜你喜欢
  • 2021-12-18
  • 2021-05-12
  • 2012-02-07
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2019-06-11
  • 1970-01-01
相关资源
最近更新 更多