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

nodejs中的承诺和异步/等待

  •  1
  • Sameer  · 技术社区  · 6 年前

    我的示例代码:

    let name;
    
     Login.findOne().then(() => {
       name = 'sameer';
     }); // consider this is async code
    
    console.log(name);
    

    所以上面的代码是异步工作的,所以现在我的console.log没有定义。

    我使用回调使代码像同步一样工作。

    let name;
    
     const callback = () => {
      console.log(name);
     };
    
     Login.findOne().then(() => {
       name = 'sameer';
       callback();
     });
    

    现在它工作得很好,

    我的问题是如何用promises和async await代替回调来替换这个小代码?

    4 回复  |  直到 6 年前
        1
  •  2
  •   jfriend00    6 年前

    await 允许您以某种同步方式编写异步代码:

    async function doIt() {
        let name = await Login.findOne();
        console.log(name);
        // You can use the result here
        // Or, if you return it, then it becomes the resolved value
        // of the promise that this async tagged function returns
        return name;
    }
    
    // so you can use `.then()` to get that resolved value here
    doIt().then(name => {
        // result here
    }).catch(err => {
        console.log(err);
    });
    

    简单的版本是这样的:

    function doIt() {
        // make the query, return the promise
        return Login.findOne();
    }
    
    // so you can use `.then()` to get that resolved value here
    doIt().then(name => {
        // result here
    }).catch(err => {
        console.log(err);
    });
    

    等待 async 所以早晚,你经常还是要用的 .then() 看看什么时候都做了。但是,很多时候 等待

    如果您有多个连续的异步操作,则会产生更大的差异:

    async function doIt() {
        let result1 = await someFunc1();
        let result2 = await someFunc2(result1 + 10);
        return someFunc3(result2 * 100);
    }
    

    如果没有等待,这将是:

    function doIt() {
        return someFunc1().then(result1 => {
            return someFunc2(result1 + 10);
        }).then(result2 => {
            return someFunc3(result2 * 100);
        });
    }
    

    加入更多的逻辑来处理中间结果或逻辑流的分支,它变得越来越复杂

    有关更多示例,请参见 How to chain and share prior results with Promises 而这个过程要简单得多 版本是。

        2
  •  1
  •   Wolf    6 年前

    虽然您可以使用匿名函数,但为了清楚起见,我将像这样声明一个名为printName的函数。

    function printName(name) {
        // if name provided in param, then print the name, otherwise print sameer.
        console.log(name || 'sameer')
    }
    

    有了承诺,你可以做到:

    Login.findOne().then(printName).catch(console.error)
    

    async function doLogin() {
         try {
           const name = await Login.findOne()
           printName(name)
         } catch(e) {
           console.error(e)
         }
    }
    
        3
  •  0
  •   jakhicks    6 年前

    因此,您当前的方法已经基于promise,您可以直接在下面添加console.log name = 'sameer'; 得到你想要的结果。 有关promises原型的概述,请参见此处- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

    Login.findOne().then(() => {
       name = 'sameer';
       console.log(name);
     });
    

    如果您想使用async/await,您需要将此逻辑包装到一个async函数中,但是您可以这样使用它:

    async function someFunction() { 
        const resultFromFindOne = await Login.findOne();
        name = 'sameer';
        console.log(name)
    }
    
        4
  •  0
  •   jonathangersam    6 年前

    如何用promises和async await代替回调来替换这个小代码

    给你,两种方法:

    /* Let's define a stand-in for your Login object so we can use Stack Snippets */
    const Login = {
      findOne: (name) => Promise.resolve(name) // dummy function
      }
    
    
    /* using promises */
    Login.findOne('sameer')
      .then(name => name.toUpperCase())  // the thing you return will be passed to the next 'then'. Let's uppercase just for fun
      .then(name => console.log('**FROM PROMISE**', name))
    
    
    /* using async/await */
    async function main() {                      // (A) only inside async can you use await
      const name = await Login.findOne('sameer') // as mentioned in (A)
      console.log('**FROM AWAIT**', name)
    }
    main() // trigger our async/await test

    干杯,