簡単学習Promise対象
10267 ワード
Promiseは非同期的にプログラムされた解決策であり、従来の解決策であるフィードバックとイベントよりも合理的で強力である.最近のプロジェクトはこれを使います.阮一峰先生の「ES 6標準入門」という本を参考にして簡単に勉強してみます.
1 Promiseの意味
Promiseとは、簡単に言えば、ある未来が終わるイベント(通常は非同期操作)が保存されているコンテナのことです.文法的には、Promiseはオブジェクトであり、非同期操作のメッセージを取得することができます.Promiseは統一APIを提供しています.様々な非同期操作は同じ方法で処理できます.
Promiseオブジェクトには以下の2つの特徴があります.オブジェクトの状態は外部の影響を受けない. いったん状態が変わると、もう変わりません. 2基本的な使い方
ES 6はPromiseオブジェクトがPromiseのインスタンスを生成するためのコンストラクタであると規定しています.例を挙げる
私たちがPromiseのインスタンスを生成した後.
ちょっと例をあげます.
3 Promise.prototype.then()
Promiseの例は、
その後、チェーンを採用した
4 Promise.prototype.ctch()
5 Promise.all()
pの状態はp 1,p 2,p 3で決まります.はp 1、p 2、p 3の状態がすべてFulFilledとなり、pの状態がFulFilledとなり、このときp 1、p 2、p 3の戻り値が1つの配列をなしてpのコールバック関数に伝達される. p 1,p 2,p 3のいずれかがRejectedによって、pの状態がそのままRejectdに変わり、このとき最初のRejectedのインスタンスの戻り値がpのコールバック関数に伝達される. 以下は具体例です.
6 Promise.race()
次の例では、指定された時間内に結果が得られなかったら、Promiseの状態をRejectに変更します.そうでないとResolivedになります.
7 Promise.resove()
既存のオブジェクトをPromiseオブジェクトに変換する必要がある場合があります.
7.1パラメータはPromiseの例です.
パラメータがPromiseの例である場合、
7.2パラメータは一つのthenableオブジェクトです.
thenableオブジェクトとは、thenメソッドを有するオブジェクト、例えば、以下のオブジェクトのことです.
7.3パラメータは、thenメソッドを有するオブジェクトではなく、またはオブジェクトではない.
パラメータが元の値であるか、またはthen方法を持たないオブジェクトである場合、
7.4どのパラメータも持たない
ですから、もしPromiseオブジェクトがほしいなら、便利な方法は直接
8 Promise.reject()
締め括りをつける
以上、Promise学習の内容についてですが、間違ったところがあれば、下記のレビューで意見を発表してください.もちろん、進級についてのPromiseの文章を置いて、皆で勉強してもいいです.
1 Promiseの意味
Promiseとは、簡単に言えば、ある未来が終わるイベント(通常は非同期操作)が保存されているコンテナのことです.文法的には、Promiseはオブジェクトであり、非同期操作のメッセージを取得することができます.Promiseは統一APIを提供しています.様々な非同期操作は同じ方法で処理できます.
Promiseオブジェクトには以下の2つの特徴があります.
ES 6はPromiseオブジェクトがPromiseのインスタンスを生成するためのコンストラクタであると規定しています.例を挙げる
var promise = new Promise(function (resolve, reject) {
// some code
if (/* */) {
resolve(value);
} else {
//
reject(error);
}
});
Promise構成関数は、
をパラメータとして受信し、
の2つのパラメータはそれぞれresolve
およびreject
である.彼らは2つの関数で、Javascriptエンジンによって提供され、自分で配置しなくてもいいです.resolve
関数の役割は、Promise
オブジェクトの状態を「未完成」から「成功」に変化させ、非同期動作が成功したときに呼び出し、非同期動作の結果をパラメータとして過去に伝えることである.reject
関数の役割は、Promise
オブジェクトの状態を「未完成」から「失敗」に変えることです.私たちがPromiseのインスタンスを生成した後.
then
方法で、Resolved
状態およびRejected
状態のコールバック関数をそれぞれ指定することができる.promise.then(function (value) {
// success
console.log(value);
}, function (error) {
// failed
console.log(error);
});
then
方法は、パラメータとして2つのコールバック関数を受け入れることができる.第1のコールバック関数はPromise
オブジェクトの状態がResolved
になったときに呼び出します.第2のコールバック関数はPromise
オブジェクトの状態がRejected
になったときに呼び出します.第二のパラメータはオプションであり、必ずしも提供する必要はない.これらの2つの関数は、パラメータとしてPromise
オブジェクトからの値を受信する.ちょっと例をあげます.
let promise = new Promise(function(resolve,reject){
console.log('Promise');
let value = 'value';
resolve(value);
});
promise.then(function(value){
console.log(value);
});
console.log('Hi');
// Promise
// Hi
// value
上記のコードでは、Promiseは新規作成後すぐ実行されますので、まず出力されるのはPromise
です.その後、then
方法で指定されたコールバック関数は、現在のスクリプトの全同期タスクを実行した後に実行されるので、Resolved
は最後に出力する.3 Promise.prototype.then()
Promiseの例は、
then
方法、すなわちthen
方法がプロトタイプオブジェクトPromise.prototype
に定義されている.その役割はPromiseの例に状態を変える際のコールバック関数を追加することである.前に述べたように、then
方法の第1のパラメータはResolved
状態のコールバック関数であり、第2のパラメータ(オプション)はRejected
状態のコールバック関数である.then
方法は、新しいPromise
である(
は元のPromiseの例ではない).したがって、チェーン式の書き方、すなわちthen
方法の後に別のthen
方法を呼び出すことができる.getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
});
上記のコードはthen
方法を用いて、二つのコールバック関数を順次指定した.最初のコールバック関数が完了すると、パラメータとして結果を返します.その後、チェーンを採用した
then
は、順番に呼び出されたコールバック関数のセットを指定することができる.このとき、前回のコールバック関数は、元のPromiseオブジェクトに戻る可能性があります.すなわち、非同期動作があります.その後、一つのコールバック関数は、Promiseオブジェクトの状態が変化するのを待って呼び出します.4 Promise.prototype.ctch()
Promise.prototype.catch
方法は、エラーが発生した場合のコールバック関数を指定する.then(null, rejection)
の別名である.getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// getJSON
console.log(' !', error);
});
上記のコードにおいて、getJSON
方法は、オブジェクトの状態がResolved
になると、then
方法で指定されたコールバック関数を呼び出します.非同期動作がエラーを出すと、状態はRejected
になり、catch
方法で指定されたコールバック関数を呼び出してこのエラーを処理します.また、then
方法で指定されたコールバック関数は、実行中にエラーが発生した場合、catch
方法によって捕捉される.p.then((val) => console.log('fulfilled:', val))
.catch((err) => console.log('rejected', err));
//
p.then((val) => console.log('fulfilled:', val))
.then(null, (err) => console.log("rejected:", err));
次は一例です.const promise = new Promise(function(resolve, reject) {
throw new Error('test');
});
promise.catch(function(error) {
console.log(error);
});
// Error: test
上記のコードでは、Promiseがエラーを出すとcatch
方法で指定されたコールバック関数によって捕獲されます.上の書き方と下の2つの書き方は等価です.//
const promise = new Promise(function(resolve, reject) {
try {
throw new Error('test');
} catch(e) {
reject(e);
}
});
promise.catch(function(error) {
console.log(error);
});
//
const promise = new Promise(function(resolve, reject) {
reject(new Error('test'));
});
promise.catch(function(error) {
console.log(error);
});
上記から分かるように、reject
方法の役割はミスを投げかけることに等しい.Promise
状態がすでにResolovedになっている場合、エラーをスローするのは無効です.const promise = new Promise(function(resolve, reject) {
resolve('ok');
// Promise
throw new Error('test');
});
promise
.then(function(value) { console.log(value) })
.catch(function(error) { console.log(error) });
// ok
一般的には、then
の状態のコールバック関数(Reject
の第2のパラメータ)は、then
の方法で定義されずに、catch
の方法が使用される.// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
});
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});
上記のコードの中で、第二の書き方は第一の書き方よりも優れています.理由は、第二の書き方が前のthen
方法の実行中のエラーをキャプチャし、同期の書き方(try/catch)にもより近いからです.したがって、catch
方法の第2のパラメータを使用せずに、常にthen
方法を使用することを提案する.5 Promise.all()
Promise.all
方法は、複数のPromiseオブジェクトのインスタンスを新たな例に包装することである.var p = Promise.all([p1, p2, p3]);
上記のコードでは、Promise.all()
方法は、パラメータとして1つの配列を受け入れ、p 1、p 2、p 3はPromiseオブジェクトの一例である.もしそうでないならば、先に以下に述べたPromise.resolve
方法を呼び出して、パラメータをPromiseの例に変換して、更に処理する(Promise.all
方法のパラメータは必ずしも配列ではないが、Iterator
インターフェースを備えていなければならず、各返却メンバーはPromiseの例である).pの状態はp 1,p 2,p 3で決まります.
var promises = [2,3,4,5].map(function(id){
console.log(id)
});
Promise.all(promises).then(function(res){
console.log(res);
resolve
}).catch(function(error){
console.log(error);
});
// promise ,
// 2 3 4 5 [undefined,undefined,undefined,undefined]
上のコードでは、Promiseは6つのPromiseの例を含む配列であり、この6つの例の状態だけがフルフィルドになり、またはそのうちの1つがrejectiedになり、Promise.all
アプローチの後のコールバック関数が呼び出される.6 Promise.race()
Promise.race
方法は、複数のPromiseのインスタンスを新たなPromiseのインスタンスにパッケージ化することでもある.var p = Promise.race([p1, p2, p])
上のコードの中で、p 1、p 2、p 3の
が率先して状態を変える限り、pの状態は変化します.その先に変わったPromiseの例の戻り値がpのコールバック関数に伝達されます.Promise.race
方法のパラメータは、Promise.all
方法と同様に、Promise例でない場合は、先に以下に述べるPromise.resolve
方法を呼び出して、パラメータをPromiseの例に変えて、さらに処理する.次の例では、指定された時間内に結果が得られなかったら、Promiseの状態をRejectに変更します.そうでないとResolivedになります.
const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
上記のコードでは、5秒以内にfetch
方法で結果が戻らないと、変数pの状態がrejectに変化し、catch
方法で指定されたコールバック関数をトリガする.7 Promise.resove()
既存のオブジェクトをPromiseオブジェクトに変換する必要がある場合があります.
Promise.resolve
方法がこの役割を果たします.const jsPromise = Promise.resolve($.ajax('/whatever.json'));
上のコードはjQueryが生成したdeferredオブジェクトを新しいPromiseオブジェクトに変えます.Promise.resolve
は、次のような書き方に等しい.Promise.resolve('foo')
//
new Promise(resolve => resolve('foo'))
Promise.resove方法のパラメータは四つの場合に分けられます.7.1パラメータはPromiseの例です.
パラメータがPromiseの例である場合、
Promise.resolve
は任意の変更を行わずに、そのままこの例に戻ります.7.2パラメータは一つのthenableオブジェクトです.
thenableオブジェクトとは、thenメソッドを有するオブジェクト、例えば、以下のオブジェクトのことです.
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
Promise.resolve
方法は、このオブジェクトをPromiseオブジェクトに変換し、thenableオブジェクトのthen方法を実行します.let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
console.log(value); // 42
});
上のコードでは、thenableオブジェクトのthenメソッドが実行されると、オブジェクトp 1の状態がresolovedとなり、最後のthenメソッドで指定されたコールバック関数が直ちに実行される.出力427.3パラメータは、thenメソッドを有するオブジェクトではなく、またはオブジェクトではない.
パラメータが元の値であるか、またはthen方法を持たないオブジェクトである場合、
Promise.resolved
方法は新しいPromiseオブジェクトを返し、状態はResovedである.const p = Promise.resolve('Hello');
p.then(function (s){
console.log(s)
});
// Hello
上のコードは新しいPromiseオブジェクトのインスタンスpを生成します.文字列ハローは非同期操作であるため(判定方法は文字列オブジェクトがthenメソッドを持っていない)、Promiseのインスタンスに戻った状態は生成からresovedであるため、コールバック関数は直ちに実行される.Promise.resolve
方法のパラメータは、同時にコールバック関数に伝えられます.7.4どのパラメータも持たない
Promise.resolved
方法は、起動時にパラメータを持たずにResoved状態のPromiseオブジェクトに直接戻すことを可能にする.ですから、もしPromiseオブジェクトがほしいなら、便利な方法は直接
Promise.resolve
メソッドを呼び出すことです.const p = Promise.resolve();
p.then(function () {
// ...
});
上のコードのpがPromiseオブジェクトです.注意したいのは、すぐにレレスのPromiseオブジェクトが本物のサイクル『イベントサイクル』(event loop)を終了した時で、次の『イベントサイクル』の開始時ではないことです.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')
が直ちに実行されるため、最初に出力される.8 Promise.reject()
Promise.reject(resson)
方法は新しいPromiseの例を返します.状態はRejectiedです.const p = Promise.reject(' ');
//
const p = new Promise((resolve, reject) => reject(' '))
p.then(null, function (s) {
console.log(s)
});
//
上のコードはPromiseオブジェクトのインスタンスpを生成し、状態はRejectedであり、コールバック関数は直ちに実行されます.締め括りをつける
以上、Promise学習の内容についてですが、間違ったところがあれば、下記のレビューで意見を発表してください.もちろん、進級についてのPromiseの文章を置いて、皆で勉強してもいいです.