提问者:小点点

nodejs中的promise和异步/等待


我的示例代码:

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();
 });

现在它工作得很好,

我的问题是如何用承诺和异步等待代替回调来替换这段小代码?


共3个答案

匿名用户

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);
});

请记住,await只能在async函数中使用,因此,您通常迟早还是要使用.then()来查看什么时候完成了所有操作。但是,很多时候,使用await可以简化顺序异步操作。

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

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

如果没有await,这将是:

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

添加更多的逻辑来处理中间结果或逻辑流的分支,在没有await的情况下,它会变得越来越复杂。

有关更多示例,请参见如何将先前的结果与承诺进行链接和共享,以及await版本要简单得多。

匿名用户

因此,您当前的方法已经是基于promise的,您可以直接在name='sameer';下添加console.log,并获得您要查找的结果。有关Prototype-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 function someFunction() { 
    const resultFromFindOne = await Login.findOne();
    name = 'sameer';
    console.log(name)
}

匿名用户

虽然您可以使用匿名函数,但为了清楚起见,我将声明一个名为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/await。它必须在一个声明为Async的函数中。

async function doLogin() {
     try {
       const name = await Login.findOne()
       printName(name)
     } catch(e) {
       console.error(e)
     }
}