Node.js 如何利用異步提升任務處理速度
今天在做一個小任務,需要調(diào)用阿里云的圖像識別接口,對 62662 張照片進行場景識別,并將結(jié)果寫到本地的 csv 文件中。
因為任務很簡單,沒想很多就開始碼。自從有了 async/await 之后,已經(jīng)很久不寫 callback 了,所以上手就寫成這樣:
本文所有代碼均有簡化,只保留關鍵過程
async fetchSceneTags(imagePath) {
try {
const result = await callAliyunAPI(imagePath);
return result.errno === 0 ? result.tags : [];
} catch(error) {
return [];
}
}
async function writeScene(paths) {
for (let i = 0, len = paths.length; i < len; i++) {
await tags = fetchSceneTags(paths[i])
writeToFile(tags);
writeStdout(`${i} / ${len}`);
}
}
function start() {
const paths = loadPaths();
writeScene(paths);
}
運行起來以后沒問題就放著忙別的去了。過了差不多 2 小時回來一看,才跑了 17180 張圖,每分鐘 144 張。這才意識到同步速度太慢了,于是停掉進程,將代碼改成下面這樣:
fetchSceneTagsAsync(imagePath, callback) {
callAliyunAPI(imagePath)
.then(result => {
const tags = result.errno === 0 ? result.tags : [];
callback(tags);
})
.catch(error => callback([]));
}
function writeSceneAsync(paths) {
const callback = tags => {
await tags = fetchSceneTagsAsync(paths[i])
writeToFile(tags);
}
paths.forEach(path => fetchSceneTagsAsync(path, callback));
}
function start() {
const paths = loadPaths();
writeSceneAsync(paths);
}
跑了一下,直接停擺了。嗯,不能一下把請求全發(fā)出去,加一個 Throttle:
fetchSceneTagsAsync(imagePath, callback) {
callAliyunAPI(imagePath)
.then(result => {
const tags = result.errno === 0 ? result.tags : [];
callback(tags);
})
.catch(error => callback([]));
}
function throttle(paths, callback) {
if(paths.length === 0) return;
const sub = paths.splice(0, 10);
sub.forEach(path => fetchSceneTagsAsync(path, callback));
setTimeout(() => throttle(paths, callback), 1000)
}
function writeSceneAsync(paths) {
const callback = tags => {
await tags = fetchSceneTagsAsync(paths[i])
writeToFile(tags);
}
throttle(paths, callback)
}
function start() {
const paths = loadPaths();
writeSceneAsync(paths);
}
重新啟動服務,觀察了一下,大約每分鐘處理 568 張圖片,速度提升約 4 倍。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
node如何將package.json中的包降為低版本或者升級為高版本
比如現(xiàn)在你用某個包的當前版本,但是你安裝的版本高了,那么你應該這么做,首先刪除node項目中的node_modules目錄,防止安裝時的包不一致,下面給大家介紹node將package.json中的包降為低版本或者升級為高版本的方法,感興趣的朋友一起看看吧2023-11-11
node.js調(diào)用腳本(python/shell)和系統(tǒng)命令
這篇文章介紹了node.js調(diào)用腳本(python/shell)和系統(tǒng)命令的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
Puppeteer 爬取動態(tài)生成的網(wǎng)頁實戰(zhàn)
這篇文章主要介紹了Puppeteer 爬取動態(tài)生成的網(wǎng)頁實戰(zhàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-11-11

