代码之家  ›  专栏  ›  技术社区  ›  Muirik

了解“await”关键字的放置位置

  •  4
  • Muirik  · 技术社区  · 7 年前

    只是为了确保我明白 async/await 好的,我想确认一下。让我先创建几个函数:

    let resolveAfter2Seconds = () => {
      console.log("starting slow promise");
      return new Promise(resolve => {
        setTimeout(function() {
          resolve(20);
          console.log("slow promise is done");
        }, 2000);
      });
    };
    
    let resolveAfter1Second = () => {
      console.log("starting fast promise");
      return new Promise(resolve => {
        setTimeout(function() {
          resolve(10);
          console.log("fast promise is done");
        }, 1000);
      });
    };
    

    现在,以这两个代码块为例:

    let concurrentStart = async () => {
      console.log('==CONCURRENT START with await==');
      const slow = resolveAfter2Seconds();
      const fast = resolveAfter1Second();
    
      console.log(await slow);
      console.log(await fast);
    }
    

    现在,是否上述功能等同于:

    let concurrentStart = async () => {
      console.log('==CONCURRENT START with await==');
      const slow = await resolveAfter2Seconds();
      const fast = await resolveAfter1Second();
    
      console.log(slow);
      console.log(fast);
    }
    

    换句话说,我可以把 await 关键字在函数调用之前 await resolveAfter25Seconds() ,或者…我可以将wait放在控制台日志中触发该函数的触发- console.log(await slow); .

    结果会是相同的吗,从这个意义上说,异步/等待在这两种情况下都将以相同的方式工作——在这种情况下,您可以用这两种方法完成相同的事情?

    1 回复  |  直到 7 年前
        1
  •  4
  •   dtanabe    7 年前

    它们的行为不同;第一个示例运行两秒钟,第二个示例运行三秒钟。

    在第一种情况下,允许慢速和快速并行启动;在第二种情况下,您强制第一个承诺在启动第二个承诺之前解决。

    一个现实世界的用例,在没有 await 如果您想并行获取多个URL,则需要对它们进行赋值。

    // assuming getUrlContents() returns a Promise
    let promises = [
        getUrlContents('http://url1.com/'),
        getUrlContents('http://url2.com/'),
        getUrlContents('http://url3.com/')
    ];
    
    // all URLs are currently fetching
    
    // now we wait for all of them; doesn't particularly matter what order
    // they resolve
    let results = [
        await promises[0],
        await promises[1],
        await promises[2]
    ];
    

    这方面的另一个变化将运行得更慢(通常不是您想要的,除非您确实需要其中一个的内容,然后才能继续下一个变化):

    let a = await getUrlContents('http://url1.com/')
    let b = await getUrlContents('http://url2.com/')
    let c = await getUrlContents('http://url3.com/')
    let results = [ a, b, c ];
    

    的下载 b 以后才开始 a 完成,等等。