記事のディレクトリ
複数のコントラクトの組み合わせにより、強力なコードロジックを形成できます。この組み合わせは
、契約のリンクと契約の統合という2つの方法で実現できます。
1つ、プロミスチェーン
各Promiseメソッドは新しいPromiseオブジェクトを返し、新しいPromiseには独自のメソッドがあるため、Promiseチェーンを実現できます。
let p = new Promise((resolve, reject) => {
console.log('first');
resolve();
});
p.then(() => console.log('second'))
.then(() => console.log('third'))
.then(() => console.log('fourth'));
// first
// second
// third
// fourth
一連の同期タスクが実装されていますが、これは非同期チェーンではありません。非同期タスクを実際に実行するには、各エグゼキュータにコントラクトのインスタンスを返させ、他のハンドラーがそれが解決されるのを待つようにします。結果を取得します(結果)
例:
let p = new Promise((resolve, reject) => {
console.log('1');
setTimeout(resolve, 1000);
});
p.then(() => new Promise((resolve, reject) => {
console.log('2');
setTimeout(resolve, 1000);
}))
.then(() => new Promise((resolve, reject) => {
console.log('3');
setTimeout(resolve, 1000);
}));
//1 (1秒后)
//2 (2秒后)
//3 (3秒后)
Promiseチェーンは、コールバック地獄の問題を解決するだけで、then()、catch()、finally()はすべてPromisesを返します。これは、同時にシリアル化できます。
2、プロミス合成
1. Promise.all()
この静的メソッドは、反復可能なオブジェクト(通常は配列)を受け取り、新しいコントラクトを返します
- 指定されたすべてのPromiseが解決されると、新しいPromiseが解決され、結果の配列が新しいPromiseの結果になります。
let p = Promise.all([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
]);
console.log(p); // Promise <pending>
p.then(()=>{
console.log(p)}); // Promise <fulfilled> <value>:[1,2,3] 当上面这些 promise 准备好时:每个 promise 都贡献了数组中的一个元素
結果配列内の要素の順序は、ソースpromise内の順序と同じであることに注意してください。最初のpromiseの解決には最も長い時間がかかりましたが、それでも結果配列の最初のpromiseです。(イテレータ順)
- 含まれている先物の少なくとも1つが保留中の場合、結果の先物も保留になります。
let p1 = Promise.all([new Promise(() =>
{
})]);// 永远pending
let p2 = Promise.all([
Promise.resolve(),
Promise.reject(),
Promise.resolve()
]);
- いずれかのプロミスが拒否された場合、Promise.allによって返されたプロミスは、このエラーですぐに拒否されます
let p =Promise.all([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error("Whoops!")), 2000)),
new Promise((resolve, reject) => setTimeout(() => (console.log('test');reject(3)), 3000))
]).catch(alert); // Error: Whoops!
//test
2番目のPromiseは拒否され、拒否の理由がPromise.all拒否の理由として使用されます(エラー:3)。後で拒否されたPromiseは
、最終的なPromise.allの理由には影響しませんが、正常に実行されます(出力テスト、サイレントにreject(3)を処理します)未処理のエラーはありません)
2. Promise.allSettled
いずれかの約束が拒否された場合、Promise.allは全体として拒否されます。すべての結果を成功させる必要がある場合、この「オールオアナッシング」の状況に役立ちます。
Promise.all([
fetch('/template.html'),
fetch('/style.css'),
fetch('/data.json')
]).then(render); // render 方法需要所有 fetch 的数据
ps。この言語はES2020の新機能であり、古いブラウザではポリフィルを使用する必要があります
3. Promise.race()
Promise.allに似ていますが、最初に解決された約束を待って、その結果(またはエラー)を取得するだけです
// 解决先发生,超时后的拒绝被忽略
let p1 = Promise.race([
Promise.resolve(3),
new Promise((resolve, reject) =>
setTimeout(reject, 1000))
]);
setTimeout(console.log, 0, p1); // Promise <resolved>: 3
Promise.all()と同様に、最初の決済後のPromiseは通常どおり実行され、すべての拒否操作はサイレントに処理されます。
三、Promise.resolve / reject
解決のためのエグゼキュータ関数に加えて、次の2つの静的メソッドも解決のために使用できます:(あまり使用されません)
1. Promise.resolve()
Promise.resolve(value)は、結果値を使用して解決済みのPromiseを作成します。
次の2つは等しい
let p1 = new Promise((resolve, reject) =>
resolve());
let p2 = Promise.resolve();
2. Promise.reject()
Promise.reject(error)は、エラーを使用して拒否されたプロミスを作成します。
4、Promise静的メソッドの概要
Promiseクラスには5つの静的メソッドがあります。
- Promise.all(promises)-すべてのpromiseが解決されるのを待つときは、結果の配列を返します。指定されたプロミスのいずれかが拒否された場合、それはPromise.allのエラーになり、他のすべてのプロミスの結果は無視されます。
- Promise.allSettled(promises)(ES2020 new method)-すべてのpromiseが解決されるのを待つとき、以下を含むオブジェクト配列の形式で結果を返します。
- ステータス:「満たされた」または「拒否された」
- 値(満たされた場合)または理由(拒否された場合)。
- Promise.race(promises)-最初に解決されたpromiseを待ち、その結果/エラーを結果として使用します。
- Promise.resolve(value)-指定された値で解決されたpromiseを作成します。
- Promise.reject(error)-指定されたエラーで拒否されたPromiseを作成します。