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

Nodejs为什么wait仅限于异步函数?

  •  2
  • Shashwat  · 技术社区  · 6 年前

    可能重复的 await is only valid in async function

    我是新手 NodeJS async-await 有点困惑。 经过一些阅读和混淆视听,这是我的理解相同。

    假设我有一个函数 sum

    function sum(a, b) {
      // print the numbers
      for (var i = 0; i < 100000; i++) {
        console.log(i);
      }
      // settimeout
      new Promise (resolve => {
        setTimeout(resolve, 1000);
      });
      return a+b;
    }
    
    function main() {
      let a = sum(5,2);
      console.log(a);
    }
    
    main();
    

    7 然后等待1秒后退出。

    await Promise .

    async function sum(a, b) {
      // print the numbers
      for (var i = 0; i < 100000; i++) {
        console.log(i);
      }
      // settimeout
      await new Promise (resolve => {
        setTimeout(resolve, 1000);
      });
      return a+b;
    }
    

    问题1: 在这里,我不明白有什么义务 async 使用 等待 异步的 只是让函数返回一个 允诺 7. .

    我觉得这个词 在函数错误地认为函数调用是异步的之前,尽管它们不是。有关于设计的澄清吗?

    问题3:

    • 在里面 ,没有同步或异步函数调用的概念,除非我们有一些阻塞函数,如计时器、远程请求和IO操作。这就是 异步等待 出现在画面中。否则,它只是一个线程,即使程序有 Promises .
    • 异步的 此外,函数只会使其返回 而不是一个值。它不会改变程序流程。也许,它只是让一些额外的机器来处理 等待 猜猜看!!
    • 异步的 不一定使任何函数(或其调用)异步。调用具有 关键字仍将是同步的,除非它包含另一个关键字 允诺 等待 进来。

    我的全部理解正确吗?

    3 回复  |  直到 6 年前
        1
  •  5
  •   Amadan    6 年前

    您的函数不是一个很好的例子,因为返回值没有以任何方式连接到 await 结果。因此,使用 Promise 是不相关的,因为代码可以在没有它的情况下重写。让我们稍微修改一下你的函数,这样它实际上会在promise中生成结果:

    function sumLater(a, b) {
      return new Promise(resolve => {
        setTimeout(() => resolve(a+b), 1000);
      });
    }
    
    async function sum(a, b) {
      // print the numbers
      for (let i = 0; i < 100000; i++) {
        console.log(i);
      }
      // settimeout
      let result = await sumLater(a, b);
      // using the awaited result
      console.log("The awaited result is", result);
      return result;
    }
    

    async 等待 可以返回从中生成的任何内容 等待 在没有承诺的情况下继续前进。原因是当前计算架构中缺少时间旅行。如果函数可以 返回将完成两小时的操作的结果 ,这将是一个令人印象深刻的突破。

    你的大多数问题都是由于术语上的混乱。不要纠结于术语的字面意思。JavaScript中没有任何东西(除了Web Workers)是同步的,乍一看,同步和同步应该是同义词。在JavaScript中,同步意味着“完全在同一个任务中执行”,异步意味着“将一个新任务放置在执行堆栈上”,就我所见,或多或少。从这个角度看,, 异步的

        2
  •  2
  •   NAVIN    6 年前

    async-await 或者promise并不能真正使函数异步。 .

    异步函数只能是setTimeout、setInterval、requestAnimationFrame和其他函数,更多关于异步函数的信息,请查看本文 How to Create asynchronous function in javascript?

    我们将用两个例子来解释这一点 异步等待 和其他 promise 他们之间有什么不同:

    1. 承诺:

    function main() {
        return new Promise( resolve => {
           console.log(1);
           resolve(true);
        });
    }
    
    main()
    .then( result => {    // result will have whatever main promise will resolve.
        console.log(2);
    });
    
    console.log(3);
    

    ```

    如果使用承诺或返回承诺会使函数异步,那么输出顺序将是

    3
    1
    2
    

    然而,仅仅返回一个承诺并不能使函数异步,因此输出是不同步的

    1
    3
    // Asynchronous happen here
    2
    

    现在 因为只有Javascript异步函数可以是异步的,并且进入callstack,然后进入事件队列,然后是的回调函数 .then( function() {}) 是javascript真正的异步函数,因此也是这种行为。 注意:调用main()返回一个promise函数。 这将用于区分promise和async await。

    1. 异步等待

    async function main() {
        console.log(1);
        return true;
    }
    
    main()
    .then( result => {  // Result have whatever main function return.
        console.log(2);
    });
    
    console.log(3);
    

    ```

    与上面类似,这也将打印

    3.
    //异步发生在这里
    

    异步等待和承诺之间有什么区别? await 任何不返回承诺并使用回调函数的异步函数,如setTimeout、setInterval、request.js、https.js函数等,都不能用async Wait处理。要处理此类函数,我们只能使用Promise,因为Promise使用回调函数,因此能够处理任何异步函数:

    function timeout() {
        return new Promise( (resolve, reject) => {
            console.log(1);
            setTimeout( function() {
                console.log(2);
                resolve(true);
            }, 1000);
        });
    }
    
    async function main() {
        console.log(3);
        let result = await timeout();
        console.log(4);
        return result;
    }
    
    main()
    .then( result => {
        console.log(5);
    });
    
    console.log(6);
    

    在达到异步功能时如预期 setTimeout 回调函数被推送到事件队列并继续处理,再次等待是异步的( 但表现得像 .then() )在事件队列上推送。其余全部继续,因此输出为:

    3
    1
    6
    // asynchronous happens here
    2
    4
    5
    

    详细解释wait的最后一个示例,从最后一个示例中删除了setTimeout的用法:

    function timeout() {
        return new Promise( (resolve, reject) => {
            console.log(1);
            console.log(2);
            resolve(true);
        });
    }
    
    async function main() {
        console.log(3);
        let result = await timeout();
        console.log(4);
        return result;
    }
    
    main()
    .then( result => {
        console.log(5);
    });
    
    console.log(6);
    

    按预期产出:

    3
    1
    2
    6
    // Asynchronous await here
    4
    5
    

    .然后() . Promise必须用于使回调函数异步并防止回调地狱。

        3
  •  0
  •   Drew Reese    6 年前

    await 关键字暂停执行 async 函数在该行上执行,直到该行解析(可能带有一个值),在该点上该函数内继续执行。两次都首先打印所有数字的原因是因为该代码在任何异步调用之前。在您的两个示例中,执行过程可能都是一样的,因为打印100000个日志所需的时间远远超过承诺解析所需的秒数。