ES 6のpromise原理
11622 ワード
promiseの役割
Promiseは非同期プログラミングのソリューションであり、従来のソリューションであるコールバック関数よりも強力であり、階層的なコールバックを回避します.それはコミュニティが最も早く提出して実現して、ES 6はそれを言語の標準に書いて、用法を統一して、今原生はPromiseの対象を提供します!
Promise使用:では、promiseはnewオペレータを使用してインスタンスを生成する必要があるため、Promiseは構造関数であることがわかります. このpromiseを初期化するには、パラメータとして1つの関数を入力する必要があります.この関数の2つのパラメータは、resolveとrejectです. resolveとrejectは2つの関数で、JavaScriptエンジンによって提供され、自分で配置する必要はありません. resolve関数の役割:Promiseオブジェクトの状態をpendingからfulfilledに変更します. reject関数の役割:Promiseオブジェクトの状態をpendingからrejectに変更します.
promiseの原理を見てみましょう
Promiseはステータスツールで、pending、fulfilled、rejectの3つのステータスがあります.そのため、まず3つのステータスを定義します.
Promiseは非同期操作を実行すると状態が遷移するので,コードはこのようになる.
上のfulfillはlow levelを比較する遷移状態法ですが、higher-levelの遷移状態法があります:resolve
resolveがメソッドgetthen()を先に呼び出しているのが見えますが、このメソッドはresultがpromiseであるかどうかを判断し、もしそうであれば、このpromiseのthenメソッド(doResolve()メソッドを使用)を呼び出し、そうでなければfulfill()メソッドを呼び出します.
ここでは、どのような状況でreject:catchからのエラーがrejectになるかを見ることができます.これまで、内部ステータスマシンを完了しましたが、resolvingというpromiseの方法を紹介します.
最後のコードだけを追加しました:私たちはre-use doResolve()メソッドを追加しました!
現在、ステータスマシンは完了していますが、変化を監視することはできません.最終的な目標は実現します.でもdone()これはもっと簡単なので、まず実現しましょう.ドン()か!私たちの目標はpromiseを実現することですdone(onFulfilled,onRejected)は、次のような特徴を持っています. onFulfilled or onRejectedの1つのみを呼び出す は、 を1回のみ呼び出す.
this.doneメソッドが行うこと:handleメソッドを実行し、パラメータを入力します.パラメータは最初が成功時のコールバック関数であり、2番目がreject時のコールバック関数です.
今、実現しましょう.thenかな~ .そしてdoneと同様に、2つのパラメータを受け入れます.1つ目は成功時コールバック関数onFulfilled、2つ目は失敗時コールバック関数onRejectedです. .thenがチェーン呼び出しを実現できるのはpromiseを返すからである.
最後に私自身は簡単版のpromiseを実現して、コンソールで実行することができて、ここをクリックします:DiPromise
転載先:https://juejin.im/post/5cc54877f265da03b8585902
Promiseは非同期プログラミングのソリューションであり、従来のソリューションであるコールバック関数よりも強力であり、階層的なコールバックを回避します.それはコミュニティが最も早く提出して実現して、ES 6はそれを言語の標準に書いて、用法を統一して、今原生はPromiseの対象を提供します!
Promise使用:
// ... some code
const promise = new Promise(function(resolve, reject) {
if (/* */){
resolve(value);
} else {
reject(error);
}
});
promiseの原理を見てみましょう
Promiseはステータスツールで、pending、fulfilled、rejectの3つのステータスがあります.そのため、まず3つのステータスを定義します.
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
// store state which can be PENDING, FULFILLED or REJECTED
var state = PENDING;
// store value or error once FULFILLED or REJECTED
var value = null;
// store sucess & failure handlers attached by calling .then or .done
var handlers = [];
}
Promiseは非同期操作を実行すると状態が遷移するので,コードはこのようになる.
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
// store state which can be PENDING, FULFILLED or REJECTED
var state = PENDING;
// store value once FULFILLED or REJECTED
var value = null;
// store sucess & failure handlers
var handlers = [];
function fulfill(result) {
state = FULFILLED; //
value = result;
}
function reject(error) {
state = REJECTED; //
value = error;
}
}
上のfulfillはlow levelを比較する遷移状態法ですが、higher-levelの遷移状態法があります:resolve
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
// store state which can be PENDING, FULFILLED or REJECTED
var state = PENDING;
// store value once FULFILLED or REJECTED
var value = null;
// store sucess & failure handlers
var handlers = [];
function fulfill(result) {
state = FULFILLED;
value = result;
}
function reject(error) {
state = REJECTED;
value = error;
}
function resolve(result) {
try {
var then = getThen(result);
if (then) {
doResolve(then.bind(result), resolve, reject)
return
}
fulfill(result);
} catch (e) {
reject(e);
}
}
}
resolveがメソッドgetthen()を先に呼び出しているのが見えますが、このメソッドはresultがpromiseであるかどうかを判断し、もしそうであれば、このpromiseのthenメソッド(doResolve()メソッドを使用)を呼び出し、そうでなければfulfill()メソッドを呼び出します.
/**
* Check if a value is a Promise and, if it is,
* return the `then` method of that promise.
*
* @param {Promise|Any} value
* @return {Function|Null}
*/
function getThen(value) {
var t = typeof value;
if (value && (t === 'object' || t === 'function')) {
var then = value.then;
if (typeof then === 'function') {
return then;
}
}
return null;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*
* @param {Function} fn A resolver function that may not be trusted
* @param {Function} onFulfilled
* @param {Function} onRejected
*/
function doResolve(fn, onFulfilled, onRejected) {
var done = false;
try {
fn(function (value) {
if (done) return
done = true
onFulfilled(value)
}, function (reason) {
if (done) return
done = true
onRejected(reason)
})
} catch (ex) {
if (done) return
done = true
onRejected(ex)
}
}
ここでは、どのような状況でreject:catchからのエラーがrejectになるかを見ることができます.これまで、内部ステータスマシンを完了しましたが、resolvingというpromiseの方法を紹介します.
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise(fn) {
// store state which can be PENDING, FULFILLED or REJECTED
var state = PENDING;
// store value once FULFILLED or REJECTED
var value = null;
// store sucess & failure handlers
var handlers = [];
function fulfill(result) {
state = FULFILLED;
value = result;
}
function reject(error) {
state = REJECTED;
value = error;
}
function resolve(result) {
try {
var then = getThen(result);
if (then) {
doResolve(then.bind(result), resolve, reject)
return
}
fulfill(result);
} catch (e) {
reject(e);
}
}
doResolve(fn, resolve, reject);
}
最後のコードだけを追加しました:私たちはre-use doResolve()メソッドを追加しました!
現在、ステータスマシンは完了していますが、変化を監視することはできません.最終的な目標は実現します.でもdone()これはもっと簡単なので、まず実現しましょう.ドン()か!私たちの目標はpromiseを実現することですdone(onFulfilled,onRejected)は、次のような特徴を持っています.
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise(fn) {
// store state which can be PENDING, FULFILLED or REJECTED
var state = PENDING;
// store value once FULFILLED or REJECTED
var value = null;
// store sucess & failure handlers
var handlers = [];
function fulfill(result) {
state = FULFILLED;
value = result;
handlers.forEach(handle);
handlers = null;
}
function reject(error) {
state = REJECTED;
value = error;
handlers.forEach(handle);
handlers = null;
}
function resolve(result) {
try {
var then = getThen(result);
if (then) {
doResolve(then.bind(result), resolve, reject)
return
}
fulfill(result);
} catch (e) {
reject(e);
}
}
function handle(handler) {
if (state === PENDING) {
handlers.push(handler);
} else {
if (state === FULFILLED &&
typeof handler.onFulfilled === 'function') {
handler.onFulfilled(value);
}
if (state === REJECTED &&
typeof handler.onRejected === 'function') {
handler.onRejected(value);
}
}
}
this.done = function (onFulfilled, onRejected) {
// ensure we are always asynchronous
setTimeout(function () {
handle({
onFulfilled: onFulfilled,
onRejected: onRejected
});
}, 0);
}
doResolve(fn, resolve, reject);
}
this.doneメソッドが行うこと:handleメソッドを実行し、パラメータを入力します.パラメータは最初が成功時のコールバック関数であり、2番目がreject時のコールバック関数です.
今、実現しましょう.thenかな~
this.then = function (onFulfilled, onRejected) {
var self = this;
return new Promise(function (resolve, reject) {
return self.done(function (result) {
if (typeof onFulfilled === 'function') {
try {
return resolve(onFulfilled(result));
} catch (ex) {
return reject(ex);
}
} else {
return resolve(result);
}
}, function (error) {
if (typeof onRejected === 'function') {
try {
return resolve(onRejected(error));
} catch (ex) {
return reject(ex);
}
} else {
return reject(error);
}
});
});
}
最後に私自身は簡単版のpromiseを実現して、コンソールで実行することができて、ここをクリックします:DiPromise
転載先:https://juejin.im/post/5cc54877f265da03b8585902