ndoe.js 預設的功能都是非同步的,一般來說程式語言都是依序從上執行到下,而 node.js 的話不是,我們來看一下一個簡單的範例
const runTimeout = () => {
setTimeout(() => {
console.log('time is up');
}, 2000);
};
runTimeout();
console.log('done');
以往我們的想像會是先拿到 time is up
在拿到 done
,但這個 case 的執行結果會先拿到 done
再拿到 time is up
,這樣的優點是你可以一次同時處理很多事情,拿到結果後進行下一步,之前要達到這樣的效果,要寫很多程式碼,然而現實生活中其實大多的功能都必須依序執行,所以有了 promise 來解決這件事情,網路上範例很多,我這邊會用最精簡的作法當作是個人的筆記。
以上方例子來說,修改方式如下:
const runTimeout = async (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time);
}, time);
});
};
const main = async () => {
try {
const r1 = await runTimeout(2000);
const r2 = await runTimeout(1000);
console.log(r1);
console.log(r2);
console.log('done');
} catch (e) {
console.error(e);
}
};
main();
我將程式買改寫成可帶入參數,這樣可以驗證他的確是依序做完的,執行結果為:
2000
1000
done
另一個情境是,執行數量是動態的話要怎麼實現,範例如下:
const runTimeout = async (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(time);
}, time);
});
};
const times = [
3000,
1000,
2000
];
const main = async () => {
try {
Promise.all(times.map(runTimeout)).then((msg) => {
console.log(msg);
console.log('done');
});
} catch (e) {
console.error(e);
}
};
main();
執行結果:
[ 3000, 1000, 2000 ]
done
第二種作法:
const runTimeout = async (time, name) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`run ${name} in ${time} secs`);
}, time);
});
};
const times = [
[3000, 'a'],
[1000, 'b'],
[2000, 'c']
];
const runners = times.map(async (item) => {
const result = await runTimeout(item[0], item[1]);
return result;
});
const main = async () => {
try {
Promise.all(runners)
.then((msg) => {
console.log(msg);
console.log('done');
});
} catch (e) {
console.error(e);
}
};
main();
執行結果:
[ 'run a in 3000 secs',
'run b in 1000 secs',
'run c in 2000 secs' ]
done
沒有留言:
張貼留言