2017-06-13 216 views
2

我想我对它的理解可能是由我与经验所影响.NETasync/await,所以我想一些代码示例:了解异步/等待上的NodeJS

我试图做一个快速控制器在返回响应之前等待5秒钟:

const getUsers = async (ms) => { 
    var wait = ms => new Promise(resolve => setTimeout(resolve, ms)); 

    await wait(ms); 
}; 


export const index = (req, res) => { 
    async() => { 
    await getUsers(5000); 

    res.json([ 
     { 
     id: 1, 
     name: 'John Doe', 
     }, 
     { id: 2, 
     name: 'Jane Doe', 
     }, 
    ]); 
    }; 
}; 

此代码不起作用,浏览器不停地加载和加载并且从不显示任何东西。

getUser功能我基于this SO answer建成,并在控制器方法的基础上,它是如何工作我的(错误的)理解,所以我想澄清和纠正:

1时,我应该使用await

就我的理解,你应该在async函数调用之前使用await。它是否正确?另外,为什么我可以在返回promise的非异步函数之前调用await?

2.什么时候应该使用async

就我的理解,您将某个功能标记为async,因此可以使用await关键字调用该功能。它是否正确?另外,[为什么]我必须将我的await getUsers(5000)调用包装在匿名异步函数中?

+0

不要将东西包装在异步匿名函数中,而您的代码中也不会执行异步匿名函数。相反,使索引函数异步并删除函数包装并返回res.json –

回答

1

要明确几个疑惑 -

  1. 您可以使用await与它返回一个承诺的任何功能。您正在等待的功能不一定必须是async
  2. 当您想在该功能中使用await关键字时,您应该使用async函数。如果你不会在功能中使用await关键字,那么你不需要使用该功能async
  3. async功能默认返回一个承诺。这就是您能够使用awaitasync功能的原因。

MDN -

当异步函数被调用,它返回一个承诺。

至于你的代码而言,它可以这样写 -

const getUsers = (ms) => { // No need to make this async 
    return new Promise(resolve => setTimeout(resolve, ms)); 
}; 

// this function is async as we need to use await inside it 
export const index = async (req, res) => { 
    await getUsers(5000); 

    res.json([ 
     { 
     id: 1, 
     name: 'John Doe', 
     }, 
     { id: 2, 
     name: 'Jane Doe', 
     }, 
    ]); 
}; 
+0

此解释非常明确。现在,剩下的只是用express路由器连接导出的异步函数'index'(这是一个返回承诺的函数),其中一个'router.get'变体接受承诺。它是否正确? –

+0

在Express中是的,你可以像这样使用它 - 'router.get('/ users',index)'。 –

0

异步的await是承诺只是语法糖。

当您希望您的代码在完整的函数上运行时,您可以像使用promise一样使用它们。

async function asyncOperation(callback) { 
    const response = await asyncStep1(); 
    return await asyncStep2(response); 
} 

是,如果你使用的承诺土地语法确切的事情:

function asyncOperation() { 
    return asyncStep1(...) 
    .then(asyncStep2(...)); 
} 

新的异步/等待语法允许你仍然使用的承诺,但它不再需要提供一个回调的链接然后()方法。

回调函数直接从异步函数返回,就好像它是一个同步阻塞函数。

let value = await myPromisifiedFunction(); 

当你计划使用在等待你的函数,你应该标记与异步关键字的功能(如在C#)

您不必创建getUsers匿名函数。