javascriptの手書きはpromiseです.
50243 ワード
プロミス
promiseの3つの状態:pending(未完成)、fulfilled(完了)、reject(拒否)
よくある操作:
次にthenのチェーンコールを追加します.
promiseの3つの状態:pending(未完成)、fulfilled(完了)、reject(拒否)
よくある操作:
new Promise((resolve, reject) => {
//
this.$axios
.get("/", { params: { id: id } })
.then(res => {
resolve(res); //
})
.catch(err => {
reject(err); //
});
})
.then(resData => {
//do something
console.log(resData);
})
.catch(err => {
console.log(err);
});
promiseコンストラクタの中で二つの関数をパラメータとして受信しました.一つのreolveと一つのrejectは成功すれば成功データに戻ります.class Promise2 {
constructor(fn) {
this._queue = [];
this._succ_mes = null;
this._error_mes = null;
this.status = "";
fn(
//
(...arg) => {
// resolve
this._succ_mes = arg;
this.status = "succ";
},
(...arg) => {
// reject
this._error_mes = arg;
this.status = "err";
}
);
}
then(fn1, fn2) {
// then
if (this.status === "succ") {
fn1(...this._succ_mes);
} else if (this.status === "err") {
if (fn2) {
// then , reject ,
fn2(...this._error_mes);
return;
}
fn1(...this._succ_mes);
} else {
this._queue.push({ fn1, fn2 });
}
}
}
以上の簡単なpromiseを実現しました.成功状態に戻った値は、失敗状態値(124;then関数)の2つの関数パラメータの戻り値を返します.次にthenのチェーンコールを追加します.
class Promise2 {
constructor(fn) {
this._queue = [];
this._succ_mes = null;
this._error_mes = null;
this.status = "";
this.promise3 = null;
fn(
//
(...arg) => {
// resolve
this._succ_mes = arg;
this.status = "succ";
this._queue.forEach(({ fn1 }) => fn1());
},
(...arg) => {
// reject
this._error_mes = arg;
this.status = "err";
this._queue.forEach(({ fn2 }) => fn2());
}
);
}
then(fn1, fn2) {
// then
this.promise3 = new Promise2((resolve, reject) => {
if (this.status === "succ") {
resolvePromise(this.promise3, fn1(...this._succ_mes), resolve, reject);
} else if (this.status === "err") {
if (fn2) {
// then , reject ,
resolvePromise(
this.promise3,
fn2(...this._error_mes),
resolve,
reject
);
return;
}
resolvePromise(this.promise3, fn1(...this._succ_mes), resolve, reject);
} else {
this._queue.push({
fn1: resolvePromise(
this.promise3,
fn1(...this._succ_mes),
resolve,
reject
),
fn2: resolvePromise(
this.promise3,
fn2(...this._error_mes),
resolve,
reject
)
});
}
});
return this.promise3; //
}
}
function resolvePromise(promise3, value, resolve, reject) {
if (promise3 === value) {
reject(new TypeError("Promise "));
}
if (
value !== null &&
(typeof value === "object" || typeof value === "function")
) {
try {
let then = value.then;
if (typeof then === "function") {
then.call(
value,
y => {
resolve(y);
},
x => {
reject(x);
}
);
}
} catch (err) {
reject(err);
}
} else {
resolve(value);
}
}
catchを追加class Promise2 {
constructor(fn) {
this._queue = [];
this._succ_mes = null;
this._error_mes = null;
this.status = "";
this.promise3 = null;
//
let resolve = (...arg) => {
// resolve
this._succ_mes = arg;
this.status = "succ";
this._queue.forEach(({ fn1 }) => fn1());
};
let reject = (...arg) => {
// reject
this._error_mes = arg;
this.status = "err";
this._queue.forEach(({ fn2 }) => fn2());
};
try {
fn(resolve, reject);
} catch (err) {
reject(err);
}
}
then(fn1, fn2) {
// then
fn1 = typeof fn1 === "function" ? fn1 : value => value;
fn2 =
typeof fn2 === "function"
? fn2
: err => {
throw err;
};
this.promise3 = new Promise2((resolve, reject) => {
if (this.status === "succ") {
try {
resolvePromise(
this.promise3,
fn1(...this._succ_mes),
resolve,
reject
);
} catch (e) {
reject(e);
}
} else if (this.status === "err") {
if (fn2) {
// then , reject ,
try {
resolvePromise(
this.promise3,
fn2(...this._error_mes),
resolve,
reject
);
} catch (e) {
reject(e);
}
return;
}
resolvePromise(this.promise3, fn1(...this._succ_mes), resolve, reject);
} else {
try {
this._queue.push({
fn1: resolvePromise(
this.promise3,
fn1(...this._succ_mes),
resolve,
reject
),
fn2: resolvePromise(
this.promise3,
fn2(...this._error_mes),
resolve,
reject
)
});
} catch (e) {
console.log(e);
}
}
});
return this.promise3; //
}
catch(fn) {
this.status === "err";
return this.then(null, fn);
}
}
非同期処理を追加then(fn1, fn2) {
// then
fn1 = typeof fn1 === "function" ? fn1 : value => value;
fn2 =
typeof fn2 === "function"
? fn2
: err => {
throw err;
};
this.promise3 = new Promise2((resolve, reject) => {
// console.log(promise3);
if (this.status === "succ") {
setTimeout(() => {
try {
resolvePromise(
this.promise3,
fn1(...this._succ_mes),
resolve,
reject
);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === "err") {
try {
if (fn2) {
// then , reject ,
resolvePromise(
this.promise3,
fn2(...this._error_mes),
resolve,
reject
);
return;
}
setTimeout(() => {
resolvePromise(
this.promise3,
fn1(...this._succ_mes),
resolve,
reject
);
}, 0);
} catch (e) {
reject(e);
}
} else {
setTimeout(() => {
try {
this._queue.push({
fn1: resolvePromise(
this.promise3,
fn1(...this._succ_mes),
resolve,
reject
),
fn2: resolvePromise(
this.promise3,
fn2(...this._error_mes),
resolve,
reject
)
});
} catch (e) {
reject(e);
}
}, 0);
}
});
return this.promise3; //
}