【问题标题】:Understanding Promise and Await理解 Promise 和 Await
【发布时间】:2018-05-22 10:33:09
【问题描述】:

我只是想了解 PromisesAsync-Await 是如何工作的。
我希望通过按该顺序记录1, 2, 3 来解决此问题。 目前它记录1, 3, 2

我知道 Promise 在这里没有真正意义,但在我的程序中它还有其他用途,因此需要保留。从Caller 函数到Test 的路线也需要保留(如果需要,您可以更改这些,但要知道它们的存在是有原因的)

我的问题是如何等待Caller 函数解决?

这是我的代码:

function Test() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('2');
      resolve();
    }, 2000);
  })
}

function Caller() {
  Test();
}

console.log('1');
Caller();
console.log('3');

我已经尝试了我所理解的,即让 Caller() 函数等待 Test Promise,但这当然会使 Caller() 函数异步,因此我们仍然得到 1、3、2

async function Caller() {
    await Test();
}

是否有某种方法可以在不使函数异步的情况下使用 await?

【问题讨论】:

  • 你应该在你的例子中等待调用者,所以把所有东西都移到一个 iife 中。另一方面,你也可以做 caller().then( () => console.log(3) )。 await 仅适用于异步函数
  • 一旦你踏上异步时间线,你将永远无法再回到同步时间线。所以console.log(3) 出现在你的异步操作之前。许多答案下提到的await 方法是一种让您感到舒适的错觉。实际上,它会将尾随代码推送到异步时间线中,而不会显式地向您显示。恕我直言,您应该作为一个现实的人遵循承诺方式,以免将同步代码与异步代码混淆。但这只是我的感觉。
  • @Icepickle 谢谢你的回复和想法 :)
  • @Redu 也感谢您的回复。我同意一旦你异步你就不能回去的问题。但是,恕我直言,您的意思是什么?我想要这个想法的解决方案。
  • 我的意思是,我更喜欢像Caller().then(_ => console.log(3)) 那样做,它明确表明您处于由Caller 函数建立的异步时间线中。

标签: javascript promise async-await


【解决方案1】:
  • 你只能await一个返回promise的函数(好吧,不完全正确,如果它不返回promise,它会创建一个立即解析的promise)
  • 只有在异步函数中时才能await

function test() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('2');
      resolve();
    }, 2000);
  })
}

async function caller() {
  console.log('1');
  await test();
  console.log('3 (this is blocked awaiting the promise');
}

caller()
console.log("This is not blocked because caller is async");

【讨论】:

    【解决方案2】:

    这是一种非常直接、简单的方式来满足您的要求。

    await 关键字只能在函数内部使用 用async定义。

    function test(ms) {
      return new Promise((resolve, reject) => setTimeout(resolve, ms))
    }
    
    async function caller() {
      console.log(1, ' - caller() started');
       
      await test(2000).then(() => {
          console.log(2, ' - test() resolved')
      });
      
      console.log(3, ' - delayed until "test()" has resolved');
      
      return 4;
    }
    
    // wait for "caller()" to resolve
    caller().then((result) => {
        console.log(result, " - caller() finished")
    });
    
    console.log(5);

    这是一篇由 Google 撰写的关于该主题的好文章:
    Async functions - making promises friendly

    引用source

    【讨论】:

      【解决方案3】:

      你可以这样使用函数:

      function sleep(ms) {
        return new Promise(r => {
          setTimeout(() => r(), ms);
        });
      }
      
      (async () => {
        console.log(1);
        await sleep(1000); // 1s
        console.log(2);
        await sleep(2000) // 2s
        console.log(3)
      })();

      【讨论】:

        【解决方案4】:

        前面的答案都是正确的,但我只是觉得这个答案更有意义。它更准确的原始问题的代码:

        function Test() {
          return new Promise((resolve, reject) => {
            setTimeout(() => {
              console.log('2');
              resolve();
            }, 2000);
          })
        }
        
        function Caller() {
          return Test();
        }
        
        (async() => {
          console.log('1');
          await Caller();
          console.log('3');
        })();

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-12
          • 2021-05-19
          • 2019-11-05
          • 1970-01-01
          相关资源
          最近更新 更多