適当な関数
sync.js
function fx() {
const a = 100 * 300;
console.log('時間です');
const ret = 'abc';
let aa = [];
for (let i = 0; i < 100; i++) {
aa.push(i);
}
console.log(ret);
const ret2 = 1000;
const a2 = 'abc';
let x = a2 + 'xyz';
console.log(ret, ret2);
}
fx();
fx();
結果は
時間です
abc
abc 1000
時間です
abc
abc 1000
同期的に動いている。
async.js
async function fx() {
await Promise.resolve(); //ここで非同期
const a = 100 * 300;
console.log('時間です');
await Promise.resolve(); //ここで非同期
const ret = 'abc';
let aa = [];
for (let i = 0; i < 100; i++) {
aa.push(i);
}
console.log(ret);
await Promise.resolve(); //ここで非同期
const ret2 = 1000;
const a2 = 'abc';
let x = a2 + 'xyz';
console.log(ret, ret2);
}
fx();
fx();
function
の前にasync
をいれ、ブレークするところにawait Promise.resolve();
をいれる。
結果は
時間です
時間です
abc
abc
abc 1000
abc 1000
非同期になった。
ブレークしたところで、処理が切り替わる。
ちなみに
async.js
function delay() {
return new Promise(resolve => setTimeout(resolve, 0));
}
async function fx() {
await delay(); //ここで非同期
const a = 100 * 300;
console.log('時間です');
await delay(); //ここで非同期
const ret = 'abc';
let aa = [];
for (let i = 0; i < 100; i++) {
aa.push(i);
}
console.log(ret);
await delay(); //ここで非同期
const ret2 = 1000;
const a2 = 'abc';
let x = a2 + 'xyz';
console.log(ret, ret2);
}
fx();
fx();
このようにsetTimeout
をPromiseにくるんで渡してもよい。
delay.js
function delay() {
return new Promise(resolve => setImmediate(resolve));
}
setImmdiate
でもOK
Promise.resolveとsetImmediateの違い
Promise.resolve()
はMicrotask Queueにタスクを追加する
setImmediate()
はTask Queueにタスクを追加する
このため、Promise.resolve()
の方が優先的に実行される
非同期関数から返り値を戻す場合
async.js
async function fx() {
await Promise.resolve(); //ここで非同期
return '終わったよ'
}
fx().then(ret => {
console.log(ret);
});
retuen
で返して、then
で受け取る。
fx()
はPromise
を返すから。
async.js
async function fx() {
await Promise.resolve(); //ここで非同期
return '終わったよ'
}
(async () => {
const ret = await fx();
console.log(ret);
})();
async
で書き換えてもOK。
長いループを非同期にする場合
loop.js
async function processAll() {
const totalIterations = 510;
const batchSize = 100;
for (let i = 0; i < totalIterations; i += batchSize) {
const start = i;
const end = Math.min(i + batchSize, totalIterations); // 最後のバッチが100回未満の場合に対応
await (async() => {
console.log(`処理中: ${start}`);
for (let i = start; i < end; i++) {
// ここで実際の処理を行う(例: API 呼び出し、データ処理など)
}
await Promise.resolve();
})();
}
console.log('すべての処理が完了しました');
}
processAll();
processAll();
100回ループするごとにブレークして非同期にループする。
処理中: 0
処理中: 0
処理中: 100
処理中: 100
処理中: 200
処理中: 200
処理中: 300
処理中: 300
処理中: 400
処理中: 400
処理中: 500
処理中: 500
すべての処理が完了しました
すべての処理が完了しました
内部のループを関数にしてもいい
loop.js
async function processBatch(start, end) {
console.log(`処理中: ${start}`);
for (let i = start; i < end; i++) {
// ここで実際の処理を行う(例: API 呼び出し、データ処理など)
}
await Promise.resolve();
}
async function processAll() {
const totalIterations = 510;
const batchSize = 100;
for (let i = 0; i < totalIterations; i += batchSize) {
const start = i;
const end = Math.min(i + batchSize, totalIterations); // 最後のバッチが100回未満の場合に対応
await processBatch(start, end);
}
console.log('すべての処理が完了しました');
}
processAll();
processAll();
以上