NodeJs 異步隊列(AsyncQueue)

原文地址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) 或去執行結果.

完善包裝成 NPM 包

上述列表實現過於簡單, 能夠作不少優化, 如隊列大小控制, 互斥代碼執行超時, 執行優先級等... 既然實現原理已代表, 錦上添花的功能就不在細化描述, 具體實現參考: AsyncQueue.json

假定代碼已經編寫完善, 目錄爲 AsyncQueue. 下面記錄發佈 NPM 包步驟:併發

  1. cd AsyncQueue # 進入代碼目錄
  2. npm init # npm 初始化 進入交互模式, 能夠一路按回車, 最終生成 package.json 文件
  3. npm login # 登陸 NPM 官網, 交互輸入 npmjs.com 網站的用戶名密碼
  4. 編輯 package.json 修改相關字段
    • name 包名, 不支持大寫, 並且極易與存在的包名衝突, 能夠經過 @用戶名/包名 格式作爲包名, 避免衝突, 缺點就是包名很長.
    • main 入口文件名, 指定 require(包名) 須要加載到文件名
    • version 包版本
    • 其它字段按需修改便可
  5. 編寫 README.md 文件, 如包安裝 npm install 包名 --save 包介紹, 用法等, 可選.
  6. npm publish --access=public # 發佈包, --access=public 顯示發佈公開包
  7. 變動完成, 更新 package.json 中 version 字段, 從新發布 npm publish --access=public 便可.
相關文章
相關標籤/搜索