Node.js 如何利用異步提升任務(wù)處理速度
今天在做一個(gè)小任務(wù),需要調(diào)用阿里云的圖像識(shí)別接口,對(duì) 62662 張照片進(jìn)行場(chǎng)景識(shí)別,并將結(jié)果寫到本地的 csv 文件中。
因?yàn)槿蝿?wù)很簡(jiǎn)單,沒想很多就開始碼。自從有了 async/await 之后,已經(jīng)很久不寫 callback 了,所以上手就寫成這樣:
本文所有代碼均有簡(jiǎn)化,只保留關(guān)鍵過程
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);
}
運(yùn)行起來(lái)以后沒問題就放著忙別的去了。過了差不多 2 小時(shí)回來(lái)一看,才跑了 17180 張圖,每分鐘 144 張。這才意識(shí)到同步速度太慢了,于是停掉進(jìn)程,將代碼改成下面這樣:
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);
}
跑了一下,直接停擺了。嗯,不能一下把請(qǐng)求全發(fā)出去,加一個(gè) 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);
}
重新啟動(dòng)服務(wù),觀察了一下,大約每分鐘處理 568 張圖片,速度提升約 4 倍。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
node如何將package.json中的包降為低版本或者升級(jí)為高版本
比如現(xiàn)在你用某個(gè)包的當(dāng)前版本,但是你安裝的版本高了,那么你應(yīng)該這么做,首先刪除node項(xiàng)目中的node_modules目錄,防止安裝時(shí)的包不一致,下面給大家介紹node將package.json中的包降為低版本或者升級(jí)為高版本的方法,感興趣的朋友一起看看吧2023-11-11
使用node.js實(shí)現(xiàn)接口步驟詳細(xì)記錄
這篇文章主要給大家介紹了關(guān)于使用node.js實(shí)現(xiàn)接口步驟的相關(guān)資料,對(duì)于剛開始不會(huì)node寫接口和調(diào)用接口,可以通過這個(gè)清晰的初步了解到整個(gè)過程,下面需要的朋友可以參考下2023-03-03
node.js調(diào)用腳本(python/shell)和系統(tǒng)命令
這篇文章介紹了node.js調(diào)用腳本(python/shell)和系統(tǒng)命令的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
Node.js開發(fā)者必須了解的4個(gè)JS要點(diǎn)
這篇文章主要介紹了Node.js開發(fā)者必須了解的4個(gè)JS要點(diǎn),Node.js是一個(gè)面向服務(wù)器的框架,立足于Chrome強(qiáng)大的V8 JS引擎。盡管它由C++編寫而成,但是它及其應(yīng)用是運(yùn)行在JS上的,需要的朋友可以參考下2016-02-02
Node.js中的HTTP請(qǐng)求與響應(yīng)詳解
本文詳細(xì)講解了Node.js中的HTTP請(qǐng)求與響應(yīng),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Puppeteer 爬取動(dòng)態(tài)生成的網(wǎng)頁(yè)實(shí)戰(zhàn)
這篇文章主要介紹了Puppeteer 爬取動(dòng)態(tài)生成的網(wǎng)頁(yè)實(shí)戰(zhàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-11-11

