約束とは何ですか?
1.主に非同期計算に使用されます
2.非同期操作をキューに入れ、目的の順序で実行し、期待される結果を返す
ことができます3.オブジェクト間でpromiseを渡して操作し、キューの処理に役立てることができます
インターフェイス(タスク)のフリーズを回避するには
-
同期:レストランに行き、場所を見つけてウェイターに電話するとします。このとき、ウェイターは「同期」ウェイターであると申し訳ありません。このテーブルを提供した後にのみ挨拶します。そのテーブルのゲストは明らかにすでに食べており、メニューなどの小さなアクションが必要ですが、ウェイターは、他の誰かの大きなアクションが完了するまで待ってから、再び挨拶するように求めています。これは同期の問題です。つまり、「注文」1234で納品された作業は、1234の注文で完了する必要があります。
-
非同期:Aによって提供された時間のかかる作業をシステムに引き渡した後、Bによって提供された作業を続行します。システムが前の作業を完了した後、コールバックまたはイベントを介してAの残りの作業を続行できます。
ABの作業の完了順序は、それらの配信順序とは関係がないため、「非同期」と呼ばれます。
基本的な文法
new Promise(
function (resolve, reject) {
// 一段耗时的异步操作
resolve('成功') // 数据处理完成
// reject('失败') // 数据处理出错
}
).then(
(res) => {console.log(res)}, // 成功
(err) => {console.log(err)} // 失败
)
最も単純なPromiseの例を見てみましょう。0から2までの乱数を生成します。1未満の場合は、一定時間待って成功を返します。それ以外の場合は失敗を返します。
function test(resolve, reject) {
var timeOut = Math.random() * 2;
log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () {
if (timeOut < 1) {
log('call resolve()...');
resolve('200 OK');
}
else {
log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}
このtest()
関数には2つのパラメーターがあり、これら2つのパラメーターは関数です。実行が成功した場合はを呼び出しresolve('200 OK')
、実行が失敗した場合はを呼び出しますreject('timeout in ' + timeOut + ' seconds.')
。test()
関数はそれ自体のロジックのみを考慮し、詳細resolve
やreject
結果の処理方法は考慮しないことがわかります。
実行関数を使用すると、Promiseオブジェクトを使用して実行し、将来のある時点で成功または失敗の結果を得ることができます。
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) {
console.log('失败:' + reason);
});
変数p1
はPromiseオブジェクトであり、test
関数の実行を担当します。test
関数は内部で非同期に実行されるため、関数がtest
正常に実行されると、Promiseオブジェクトに次のように通知します。
// 如果成功,执行这个函数:
p1.then(function (result) {
console.log('成功:' + result);
});
ときにtest
関数が失敗した、私たちは約束のオブジェクトを教えて:
p2.catch(function (reason) {
console.log('失败:' + reason);
});
Promiseオブジェクトはチェーン化できるため、上記のコードは次のように簡略化できます。
new Promise(test).then(function (result) {
console.log('成功:' + result);
}).catch(function (reason) {
console.log('失败:' + reason);
});
どこでjob1
、job2
そしてjob3
は約束の対象です。
次の例は、結果を取得するために非同期計算を必要とする一連のタスクをシリアルに実行する方法を示しています。
'use strict'; var logging = document.getElementById('test-promise2-log'); while (logging.children.length > 1) { logging.removeChild(logging.children[logging.children.length - 1]); } function log(s) { var p = document.createElement('p'); p.innerHTML = s; logging.appendChild(p); }
// 0.5秒后返回input*input的计算结果:
function multiply(input) {
return new Promise(function (resolve, reject) {
log('calculating ' + input + ' x ' + input + '...');
setTimeout(resolve, 500, input * input);
});
}
// 0.5秒后返回input+input的计算结果:
function add(input) {
return new Promise(function (resolve, reject) {
log('calculating ' + input + ' + ' + input + '...');
setTimeout(resolve, 500, input + input);
});
}
var p = new Promise(function (resolve, reject) {
log('start new Promise...');
resolve(123);
});
p.then(multiply)
.then(add)
.then(multiply)
.then(add)
.then(function (result) {
log('Got value: ' + result);
});
Promiseは、いくつかの非同期タスクを連続して実行するだけでなく、非同期タスクを並行して実行することもできます。
ページチャットシステムを想像してみてください。2つの異なるURLからユーザーの個人情報と友達リストを取得する必要があります。これら2つのタスクは並行して実行できます。Promise.all()
実装は次のとおりです。
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
複数の非同期タスクがフォールトトレランスのためのものである場合があります。たとえば、ユーザーの個人情報を2つのURLに同時に読み取るには、最初に結果を返すだけで済みます。この場合、以下を使用しますPromise.race()
。
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
p1
実行が高速であるため、Promisethen()
は結果を取得し'P1'
ます。p2
実行は続行されますが、実行結果は破棄されます。
Promiseを組み合わせて使用すると、多くの非同期タスクを組み合わせて、並列およびシリアルで実行できます。