Node.js中的承诺和异步/等待

时间:2018-10-04 07:31:37

标签: javascript node.js callback promise async-await

我的示例代码:

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

现在可以正常工作了,

我的问题是,如何用promise和async await代替回调来代替这段小代码?

4 个答案:

答案 0 :(得分:2)

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

如果没有等待,它将是:

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

添加更多逻辑来处理中间结果或逻辑流分支,如果没有await,它将变得越来越复杂。

有关更多示例,请参见How to chain and share prior results with Promises以及await版本更简单。

答案 1 :(得分:0)

因此,您当前的方法已经基于承诺,您可以直接在name = 'sameer';下添加console.log并获得所需的结果。 请参阅此处,以了解Promise原型的概述-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)
}

答案 2 :(得分:0)

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

var a = 1
var b = 2
var c = Int("\(a)\(b)") // Result 12

var a1 = 12
var b1 = 34
var c1 = Int("\(a1)\(b1)")  // Result 1234


var a2 = 122344
var b2 = 9022
var c2 = Int("\(a2)\(b2)") // Result 1223449022

有了承诺,您可以做到:

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)

答案 3 :(得分:0)

  

如何用promises和async等待而不是回调代替这段小代码

在这里,有2种方法可以做到:

/* 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

干杯