原文地址git
NodeJs 程序並無鎖概念, 多是單線程程序的緣故吧. 可是存在異步回調, 也就形成併發執行統一代碼的可能性, 固然這裏併發不是真正意義上的併發. 是同一線程在不一樣時間點執行統一代碼. 事故相似代碼以下:github
// 阻塞函數 const sleep = async (ms = 0) => { return new Promise((resolve, reject) => { return setTimeout(resolve(true), ms); }) } let total = 0; const demoFunc = async () => { let count = total; await sleep(2000) total = count + 1; } demoFunc(); demoFunc(); sleep(4000); console.log(total); // 輸出 1
示例是一個很簡單的自增行爲, 不少人可能會說直接在demoFunc()前加 await 不是就是指望結果了, 而後事實多是真的沒法直接這樣作, demoFunc 函數表明實際上是一個web請求的處理. total 是數據讀存(db 或 file).
我指望的結果是 2, 實際結果卻爲 1. 具體狀況不一樣可能有不一樣解決方案, 本文提供一種異步隊列機制去順序執行須要互斥的的代碼.web
只用使用 Promise 鏈執行順序執行互斥代碼.npm
let queue = Promise.resolve(true); const queue_exec = async (fn) => { queue = queue.then(() => { try { return Promise.resolve(fn()); } catch(err) { return Promise.reject(err); } }); return queue; } // 上述示例換成以下調用便可 queue_exec(demoFunc); // 在實際的請求中能夠用 await queue_exec(demoFunc) 或去執行結果.
上述列表實現過於簡單, 能夠作不少優化, 如隊列大小控制, 互斥代碼執行超時, 執行優先級等... 既然實現原理已代表, 錦上添花的功能就不在細化描述, 具體實現參考: AsyncQueue.json
假定代碼已經編寫完善, 目錄爲 AsyncQueue. 下面記錄發佈 NPM 包步驟:併發
npm install 包名 --save
包介紹, 用法等, 可選.npm publish --access=public
便可.