ホームページ  >  記事  >  ウェブフロントエンド  >  ECMAScript6 の Promise とは何ですか?用途は何ですか? (例付き)

ECMAScript6 の Promise とは何ですか?用途は何ですか? (例付き)

不言
不言転載
2018-10-24 11:44:472063ブラウズ

この記事の内容は、ECMAScript6 の Promise とは何ですか?用途は何ですか? (例付き) なので、困っている友人の参考になれば幸いです。

勉強を終えたところですが、ざっくりとした感想です。その後の学習や補足のために整理して記録し、理解を深めることができます。

Promise とは

Promise は、new を通じて Promise オブジェクトを生成できるコンストラクターです。

Promise の用途は何ですか。

私の現在の感想は、非同期プロセスの操作がより便利で、イベントを制御するプロセスがより明確で直感的であることです。チェーン呼び出しが可能です

Promise の特性

ES6 Getting Started より抜粋

Promise オブジェクトには次の 2 つの特性があります。
(1) オブジェクトのステータスは外界の影響を受けません。 Promise オブジェクトは非同期操作を表し、保留中 (進行中)、履行済み (成功)、および拒否 (失敗) の 3 つの状態があります。非同期操作の結果のみが現在の状態を決定でき、他の操作はこの状態を変更できません。これがプロミスの名前の由来でもあり、英語で「コミットメント」という意味があり、他の手段では変えられないという意味です。
(2) 一度変化した状態は再度変化せず、いつでもこの結果が得られます。 Promise オブジェクトの状態が変化する可能性は 2 つだけです。保留中から実行済みへ、および保留中から拒否へです。この 2 つの状況が発生する限り、状態は固定され、再び変化せず、この結果が維持されます。 解決しました。変更がすでに行われている場合は、Promise オブジェクトにコールバック関数を追加すると、結果がすぐに得られます。イベントとは全く違いますが、聞き逃してまた聞き直すと結果が出ないのがイベントの特徴です。

いくつかの簡単な例を通じて理解します

new を通じて単純な Promise オブジェクトを構築します

let p = new Promise((resolve, reject) => {});

渡された 2 つのパラメーターは、Promise オブジェクトの状態を制御するために使用されます。 p を出力してステータスを確認します。
Promise {__proto__: Promise[[PromiseStatus]]: "pending"[[PromiseValue]]: unknownこれは初期状態の pending です
そして解決し、拒否しますPromise の状態を制御できます

//resolve()
let p = new Promise((resolve, reject) => resolve("123")); //Promise {<resolved>: "123"}
//reject()
let p = new Promise((resolve, reject) => reject("123")); //reject()后是返回一个失败状态的Promise,不需要用catch来捕获不写catch会报错
p.catch(data => console.log(data));    
console.log(p);    //Promise {<rejected>: "123"}   123

前述のキャッチ、then もあります
シンプルにしましょう: then(f1, f2) は 2 つの関数パラメータを入力でき、1 つのパラメータは解決されます。 真ん中のパラメータを次のパラメータに置き換えます。 f1 を実行し、2 番目のパラメータを拒否のパラメータを f2 に置き換えて実行します。2 番目のパラメータは catch に置き換えることができ、Catch は then()

let p = new Promise((resolve, reject) => {
    
    let n = Math.ceil(Math.random() * 10);
    n > 5 ? resolve(n) : reject(n);
});
p.then(
    data => console.log(data),
    data => console.log(data),
)
## でエラーをキャプチャできます。代わりにキャッチして、then

let p = new Promise((resolve, reject) => {
    
    resolve("yes")
});
p.then(
    data => {console.log(data),console.log(a)}

).catch(data => console.log(data));
//yes
//ReferenceError: a is not defined
のエラーをキャプチャします。これは、then の処理後に Promise オブジェクトが返されるため、連鎖呼び出しが容易になります。then にはリターンがないため、どうやって Promise オブジェクトが存在できるのでしょうか。

then または catch は、戻り値が明示的に指定されていない場合でも、常に新しい満たされた状態の Promise オブジェクトを自動的にラップします。

これを印刷すると、次のことがわかります:

Promise {: 未定義} 次に、返された Promise オブジェクトを表示して確認できます。

let p = new Promise((resolve, reject) => resolve("yes"));
p.then(data => Promise.resolve("第二个Promise")).then(data => console.log(data));   //第二个Promise
can see

p.then(data => Promise.resolve("Second Promise"))返される Promise オブジェクトは Promise {: "Second Promise"} であり、 value をパラメータとして 2 番目に入力し、

Promise.resolve(value | Promise | thenable) を実行して Promise オブジェクトを作成します

最初のパラメータは空または元の値で、Promise オブジェクトが作成されます状態は直接解決されます state

Promise.resolve('f')
// 等价于
new Promise(resolve => resolve('f'))
The Second

then メソッドを持つオブジェクトは注目に値します

let thenable = {
    then :(resolve, reject) => resolve("thenable")
}

let p = Promise.resolve(thenable);
console.log(p);
Promise オブジェクトの状態は -> によって決定されます; 3 番目のパラメータはインスタンス化された Promise オブジェクトです。
let p1 = new Promise((resolve, reject) => false);
let p = Promise.resolve(p1);
console.log(p);p 状態は p1 状態と一致します <p></p>Promise.reject(value) は Promise オブジェクトを作成します<p>解決とは異なります。 はい: 値をパラメータとして <br></p>
<pre class="brush:php;toolbar:false">const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};

Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
catch メソッドに直接渡します。 catch メソッドのパラメータは、reject によってスローされた「エラー」文字列ではなく、thenable オブジェクトです。

Promise.all

複数の Promise インスタンスを新しい Promise インスタンスにラップします。 const p = Promise.all([p1, p2, p3]);

(1) p1、p2、p3のステータスがすべて満たされた場合にのみ、pのステータスが満たされます。このとき、p1、p2、p3の戻り値は配列を形成し、 のコールバック関数に渡されます。 p.

(2) p1、p2、p3 のいずれかが拒否された場合、p のステータスは拒否されます。このとき、最初に拒否されたインスタンスの戻り値がコールバック関数に渡されます。 p.

all 内のすべてのオブジェクトが実行されるまで待機し、配列をコールバック関数に渡します。その後

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));
Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));    // ["p", "p2", "p2"]
let p = new Promise((resolve, reject) => resolve('p'));
let p1 = new Promise((resolve, reject) => reject('p2'));
let p2 = new Promise((resolve, reject) => resolve('p2'));
Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p2
Promise.race

all との違いは次のとおりです: p1 である限り、 p2、p3 インスタンスの 1 つが最初に状態を変更し、それに応じて p の状態も変更します。最初に変更された Promise インスタンスの戻り値が p のコールバック関数に渡されます。

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));
Promise.race([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p
Promise オブジェクトのコールバック関数と setTimeout の順序

An event loop has one or more task queues. A task queue is an ordered list of tasks, which are algorithms that are responsible for such work as: events, parsing, callbacks, using a resource, reacting to DOM manipulation…Each event loop has a microtask queue. A microtask is a task that is originally to be queued on the microtask queue rather than a task queue.
  浏览器(或宿主环境) 遵循队列先进先出原则, 依次遍历macrotask queue中的每一个task, 不过每执行一个macrotask, 并不是立即就执行下一个, 而是执行一遍microtask queue中的任务, 然后切换GUI线程重新渲染或垃圾回收等.
  Event Loop (事件循环)拥有如下两种队列
  macrotask queue, 指的是宏任务队列, 包括rendering, script(页面脚本), 鼠标, 键盘, 网络请求等事件触发, setTimeout, setInterval, setImmediate(node)等等.
  microtask queue, 指的是微任务队列, 用于在浏览器重新渲染前执行, 包含Promise, process.nextTick(node), Object.observe, MutationObserver回调等.
  process.nextTick > promise.then > setTimeout ? setImmediate

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。

setTimeout(function() {
  console.log(4)
}, 0);
new Promise(function(resolve) {
  console.log(1);
  for (var i = 0; i < 10000; i++) {
    i == 9999 && resolve()
  }
  console.log(2);
}).then(function() {
  console.log(5)
});
console.log(3);  //1 2 3 5 4

以上がECMAScript6 の Promise とは何ですか?用途は何ですか? (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。