【问题标题】:JS async (async/await) returns promise but also executes the functionJS async (async/await) 返回promise但也执行函数
【发布时间】:2018-03-27 07:28:15
【问题描述】:

JavaScript 异步函数返回 Promise,但也执行该函数。这有点违背了目的。请解释。还有一种方法可以通过仅使用 async/await(不是 Promise)来返回 Promise 而不是执行。

https://jsfiddle.net/ravilution/woxkossp/

function wait(ms){
  var start = new Date().getTime();
  var end = start;
  while(end < start + ms) {
    end = new Date().getTime();
  }
}

const fn = async (value) => {
  console.log("start fn ", value)
  wait(2000);
  console.log("end fn ", value)
  return value;
}

const main = async () => {
  var promiseForFn = fn(3);
  console.log("promiseForFn ", promiseForFn);
  var value = await promiseForFn;
  console.log("value ", value);
}

main()

https://jsfiddle.net/ravilution/o44kbj9p/

const wait = async(ms) => {
  var start = new Date().getTime();
  var end = start;
  while (end < start + ms) {
    end = new Date().getTime();
  }
}

const fn = async(value) => {
  console.log("start fn ", value)
  await wait(2000);
  console.log("end fn ", value)
  return value;
}

const main = async() => {
  var promiseForFn = fn(3);
  console.log("promiseForFn ", promiseForFn);
  var value = await promiseForFn;
  console.log("value ", value);
}

main()

将函数标记为async 并不是让它真正异步的原因是答案。感谢@another-guy

【问题讨论】:

  • 您的wait 函数是同步的。当您从fn 使用它时,您期望会发生什么?
  • @another-guy 请帮助我理解。我将等待转换为异步。似乎仍然没有按预期工作。 jsfiddle.net/ravilution/o44kbj9p

标签: javascript node.js async-await


【解决方案1】:

async 关键字只能用于在其代码块中使用 await 的函数。在您的情况下,“等待”功能是同步的(并阻止事件循环)-因此不需要异步字。

【讨论】:

    【解决方案2】:
    • 有很多方法可以实现代码的异步性。回调、setTimeoutPromises 等内置函数是一些常见的。
    • 将函数标记为async不是使它真正异步的原因。它允许您在要等待 Promise 的地方使用关键字 await
    • 是的,await/async 仅适用于 Promise。它们对于以应用于异步代码的命令式(同步)样式表示分支和更复杂的流控制很有用。

    试试下面的代码,看看它是如何工作的,希望对你有帮助:


    function wait(ms, text) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('complete', text);
          resolve({});
        }, ms);
      });
    };
    
    async function doTwoThings() {    // This func will return a Promise
      await wait(2000, 'BBB');        // - to which you can subscribe with `.then`
      await wait(1000, 'AAA');        // - or `await` on within another `async` function.
      return 'Both done';
    }
    
    doTwoThings()
      .then(
         result => console.info('Done done done!', result),
         err => console.error('Oooops', err)
      );
    

    【讨论】:

    • 我来自 C# 世界。并且认为提到异步会使函数异步。我的错。在链条的深处,最终的功能不是一直都是同步的吗?那个功能不应该告诉上面的每个人吗,请不要等我,等我回来再说吧。我认为这个承诺会通过提到的异步来创建,就像在 C# 中一样。我会接受答案。
    • Deep down the chain doesn't the final function behave synchronous all the time? 是的,它必须。这就是我做doTwoThings().then( ... ) 的原因——我认为在根级别上await 是不可能的。至少,我不知道如何做到这一点......
    • @ravi - 仅将 async 关键字添加到 c# 中的函数不会使任何内容异步。它只允许您在该方法中使用 await
    • @FredrikLundin。正确的。返回 Task 确实如此。这是 JS 中的承诺。我现在什么都能理解了。
    • @Ravi 虽然从技术上讲它们不一定是 100% 精确匹配,但我最终使用了几乎相同的心智模型,因为这个模型 a) 简单; b) “足够好”; c) 易于学习(因为建立在我已经知道的基础上)。是的,我也是从 .NET 领域来到 JS/TS 的。
    猜你喜欢
    • 2017-09-11
    • 2021-08-06
    • 2017-10-21
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 2022-08-22
    相关资源
    最近更新 更多