2017-06-13 257 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匿名函數。