一.インターフェース分析
###1.コア機能
- resolve(value)/reject(err)
コンストラクタパラメータ resolve/reject は静的メソッドでもインスタンスメソッドでもありませんが、データエントリーポイントであるため、promise API のコアです。promise メカニズムの大部分の秘密はここにあり、すべての公開インターフェースはこれを基に動作します
- then(onFulfilled, onRejected)
resolve/reject 以外に、then は絶対に最も重要です。他のすべてのインスタンスメソッド/静的メソッドは必須ではありませんが、then は不可欠です。言い換えれば、new Promise できて then もサポートできれば、promise メカニズム全体が完成し、他のインターフェースはすべて錦上添花のもので、promise をより使いやすくするだけです
###2.インスタンスメソッド
- catch(onRejected)
promise.then(null, onRejected) と等価で、ユーザーは少し少ないコードを書け、同時に意味を付与します(catch error)
###3.静的メソッド
- Promise.resolve(value)
wrapper を提供し、value が Promise インスタンスかどうかわからない時に、このメソッドを使用して包装された Promise インスタンスを取得できます。内部メカニズムは比較的複雑で、詳細情報は [6.Promise.resolve(value) 解決](/articles/完全理解 promise/#articleHeader14) を参照
- Promise.reject(reason)
同様に wrapper を提供し、否定 Promise を作成するショートカット方式で、内部メカニズムは Promise.resolve(value) よりずっとシンプルです
- Promise.all(iterable)
すべて正常に完了するか、またはエラーで中断され、未完成のものはすべて停止
- Promise.race(iterable)
「競争」、結果が肯定か否定かに関わらず、最も速いもののみ
###4.高度機能
-
結果自動後投げ
// 错误后抛 new Promise(function(resolve, reject) {reject('x')}) .then(null) .then(null) .catch(function(err) {console.log(err)}) // 值后抛 new Promise(function(resolve, reject) {resolve('x')}) .catch(null) .catch(null) .then(function(future) {console.log(future)})
エラーは最後の catch に投げられ、「食べられ」なければ自動的に後投げされ、最後に「食べられる」か、トップ層に投げられてエラー報告
-
結果自動外投げ
// 外层 then 能够拿到内层 future 和 error new Promise(function(resolve, reject) { resolve(new Promise(function(resolve, reject) { resolve(12); // reject(new Error('reject in nested Promise')); }).then(function(future) { return future + 1; }, function(error) { return new Error('reject again in nested Promise'); })); }).then(onFulfilled, onRejected);
外層の then は内層の future と error を取得でき、手動で状態を維持する必要を避け、エラー集中処理にも有利
二.難点
難点は promise メカニズム自体が非同期であることです。例は以下の通り:
var p = new Promise(function(resolve, reject) {resolve(1)}).then(function(future) {return 2;});
// 立即输出 p
console.log(p);
// 1s 后输出 p
setTimeout(function() {
console.log(p);
}, 1000);
即時出力の結果は:
// console
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
1 秒後出力の結果は:
// console
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
このような非同期メカニズムの下で、return と throw はどちらも問題になります。例えば:
// 异步
function nextTick(fn) {
setTimeout(fn, 0);
}
// test
try {
nextTick(function() {
throw new Error('x');
});
}
catch (err) {
console.log('err: ' + err.message);
}
結果はエラーを catch できず、x はトップ層に投げられ、コンソールに表示されます。try..catch を入れることを簡単に考えられます。はい、エラーは確かに catch されましたが、どのように外層に通知すればよいでしょうか?
return と throw はすべて値伝達の手段で、非同期環境では直接使用できず、自分で 1 つの値伝達メカニズムを実装する必要があります。これが難点です
P.S. ある記事で try...catch の欠点について言及しています。詳細情報は 前端コード異常監視 を参照
三.プロジェクトアドレス
アドレス:ayqy / myPromise - コードホスティング - オープンソース中国コミュニティ
注意:現在バージョン(v0.1.0 2015/12/13)には大きな問題があり、絶対に直接使用しないでください。現在内部メカニズムは同期のためです
P.S. バージョンが使用可能に更新された時、筆者はここで説明します。それ之前は、より信頼できる taylorhakes/promise-polyfill · GitHub を使用することを推奨。非常に軽量な実装です
参考資料
- [翻訳] We have a problem with promises:promise の実行メカニズムを理解すればこれらの問題は発生しません。4 種類の promise の違いについても言うことはありませんが、文中で言及されたエラーは注意に値します
コメントはまだありません