此文只是粗略介紹使用方法,欲瞭解核心概念請參考官方文檔或其餘資料。html
舉例寫文章詳情頁面的時候的一個場景:首先更改文章詳情中的 PV,而後讀取文章詳情,而後根據文章詳情中文章 Id 查閱該文章評論和該文章做者信息。獲取所有數據以後渲染文章詳情頁。數據庫操做都是異步的,最直接想到的辦法就是一層一層的回調函數,問題出來了:十分不雅觀,要是層再多一點還會有更多麻煩。怎麼解決?業內爲了處理異步操做問題也是拼了,什麼async,q,bluebird,co,處理方式不一樣,各有千秋,感興趣能夠了解一下,可是驚喜的發現nodejs 7.6已經默認支持ES7中的 async/await 了,結合ES6中的 promise對象,用起來不亦樂乎的。node
Async/await的主要益處是能夠避免回調地獄(callback hell),且以最接近同步代碼的方式編寫異步代碼。數據庫
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { // 返回 ‘ok’ resolve('ok'); }, time); }) }; var start = async function () { let result = await sleep(3000); console.log(result); // 收到 ‘ok’ };
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { // 模擬出錯了,返回 ‘error’ reject('error'); }, time); }) }; var start = async function () { try { console.log('start'); await sleep(3000); // 這裏獲得了一個返回錯誤 // 因此如下代碼不會被執行了 console.log('end'); } catch (err) { console.log(err); // 這裏捕捉到錯誤 `error` } };
const search = async () => {
const project = await Project.findById(id)
Project.belongsToMany(User, { through: 'UserProject' })
const users = await project.getUsers()
Project.hasMany(Task)
const task = await project.getTasks()
return { project, users, task }
}
search().then(data => res.json(data)).catch((err) => {
console.log(err)
res.send({ name: err.name, msg: err.message })
})json
var start = async function () { for (var i = 1; i <= 10; i++) { console.log(`當前是第${i}次等待..`); await sleep(1000); } };
再循環中使用不須要閉包,每次循環會被阻塞。api
let [foo, bar] = await Promise.all([getFoo(), getBar()]); Promise.all() // 所有完成時返回 Promise.race() // 任意一個完成時返回 // 比下面按順序執行會節省一些時間 let foo = await getFoo(); let bar = await getBar();
最前面提到的場景:(綜合使用)promise
var showArticle = async function () { await new Promise(function (resolve, reject) { PostModel.incPv(postId, function (result) { resolve(result); }); });// pv 加 1 var post = await new Promise(function (resolve, reject) { PostModel.getPostById(postId, function (article) { resolve(article); }); });// 獲取文章信息 await new Promise(function (resolve, reject) { userModel.getUserById(post.author,function (author) { post.author=author; resolve(); }) });//獲取文章做者 var comments = await new Promise(function (resolve, reject) { CommentModel.getComments(post._id, function (comment) { resolve(comment); }); });// 獲取該文章全部留言 for(var i=0;i<comments.length;i++){ await new Promise(function (resolve, reject) { userModel.getUserById(comments[i].author,function (author) { comments[i].author=author; resolve(); }) });//獲取文章留言做者 } if (!post) { req.session.error = '該文章不存在'; return res.redirect('/post'); } res.render('post',{post: post, comments: comments}); }; showArticle();