toc
Promise
3つの状態
保留→解決済み→または保留→却下
この変化は不可逆的です。
const p1 = new Promise((resolve, reject) => {
})
console.log("p1", p1)
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
})
})
console.log("p2", p2)
setTimeout(() => console.log("p2-setTimeout", p2))
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject();
})
})
console.log("p3", p3)
setTimeout(() => console.log("p3-setTimeout", p3))
州のパフォーマンス
- 保留状態は、then and catchのトリガーにはなりません。
- トリガーを解決し、キャッチ。
- rejectはcatchをトリガーします。
その後とキャッチの状態変化
- を返し、正常であれば解決済み、エラーがあれば拒否されます。
- キャッチが正常であればresolvedを返しますが、エラーがあればrejectを返します。
const p1 = Promise.resolve().then(() => {
return 100;
});
console.log("p1", p1);
p1.then(() => {
console.log("p1 then");
});
const p2 = Promise.resolve().then(() => {
throw new Error("then error");
});
console.log("p2", p2);
p2.then(() => {
console.log("p2 then");
}).catch((err) => {
console.log("p2 catch error", err);
});
const p3 = Promise.reject("p3 error").catch(err => {
console.error(err);
});
console.log("p3", p3); // resolved thenコールバックをトリガーする
p3.then(() => {
console.log("p3 then");
});
const p4 = Promise.reject("p3 error").catch(err => {
throw new Error("p4 catch error");
});
console.log("p4", p4); // rejected catchコールバックをトリガーする
p4.then(() => {
console.log("p4 then"); // 印刷しない
}).catch((err) => {
console.log("p4 catch", err);
});
プロミストピック
Promise.resolve().then(() => {
console.log(1);
}).catch(() => {
console.log(2);
}).then(() => {
console.log(3);
})
12
Promise.resolve().then(() => { // エラーは拒否された
console.log(1);
throw new Error("error1");
}).catch(() => { // エラーが報告されなければresolvedを返す
console.log(2);
}).then(() => {
console.log(3);
})
123
Promise.resolve().then(() => {
console.log(1);
throw new Error("error1");
}).catch(() => {
console.log(2);
}).catch(() => {
console.log(3);
})
12
async-await
非同期開発
- 非同期コールバック コールバックと地獄
質問:コールバック地獄
Promiseは、連鎖した呼び出しをキャッチするだけでなく、コールバック関数にも基づきます。
async-awaitは、コールバック関数を完全に排除した同期構文です。
async-awaitの基本的な使い方
- await続いてPromise関数
- 非同期関数が続きます。
async-awaitPromise との関係
async-awaitは、非同期コールバックを排除する究極の手段です。
しかし、プロミスは互いに排他的なものではなく、補完的なものです。
非同期関数は Promise オブジェクトを返す必要があります。
try-catch は .catch の代わりに例外をキャッチします。
非同期実行は Promise オブジェクトを返さなければなりません。
async function fn1() {
// return "fn1" // returnPromiseに相当する.resolve("fn1")
return Promise.resolve(200);
}
const res1 = fn1();
console.log(res1);
res1.then(data => {
console.log("res1 data", data);
});
await は then() と同じです。
(async function () {
const p1 = Promise.resolve(300);
const data = await p1;
console.log("data", data);
})();
(async function () {
const p1 = await 400; // await Promiseに相当する。.resolve(400)
const data = await p1;
console.log("data", data);
})();
(async function () {
const p1 = await fn1();
const data = await p1;
console.log("data", data);
})();
トライキャッチ
(async function () {
const p4 = Promise.reject("err");
try{
const res = await p4;
console.log(res);
}catch (err) {
console.log("err1", err)
}
})();
(async function () {
const p5 = Promise.reject("err");
const res = await p4; // この時点では拒否状態であり、実行されない。-catch
console.log(res)
})();
非同期の本質は、やはりコールバック関数です。
- jsはシングルスレッド、非同期はイベントループに基づきます。
- 非同期awaitは単なる構文糖です。
async function async1() {
console.log("async1 start");
await async2();
// await 次の行は非同期になる。
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
console.log("script start");
async1();
console.log("script end");
プリンタブル
script start
async1 start
async2
script end
async1 end
最初に同期コードを実行
イベントループの開始
非同期コードの実行
非同期関数の追加
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
await async3();
console.log("async1 end 2");
}
async function async2() {
console.log("async2");
}
async function async3() {
console.log("async3");
}
console.log("script start");
async1();
console.log("script end");
プリンタブル
script start
async1 start
async2
script end
async1 end
async3
async1 end 2
アプリケーションシナリオ
- for-in は通常の同期トラバーサルです。
- for-of は非同期走査によく使われます。
通常の非同期トラバーサル・コードは次のとおりです。
function muti(num) {
return new Promise(resolve => {
setTimeout(() => {
resolve(num * num);
}, 1000);
});
}
const nums = [1, 2, 3];
nums.forEach(async (i) => {
const res = await muti(i);
console.log(res);
});
1秒後、すべて同時にプリントアウト
1枚ずつ印刷する必要がある場合は、for-ofメソッドを使用する必要があります。
awaitを実行するには、非同期関数でラップする必要があることに注意してください。
function muti(num) {
return new Promise(resolve => {
setTimeout(() => {
resolve(num * num);
}, 1000);
});
}
const nums = [1, 2, 3];
!(async function () {
for (let i of nums) {
const res = await muti(i);
console.log(res);
}
})();





