私はaxiosライブラリを使用し、then()、catch()、finally()を使用しています。 Chromeで完全に動作します。ただし、finally()メソッドはMS Edgeでは機能しません。ポリフィルやシムを使って調査したところ、道に迷いました。私はウェブパックやトランスパイルを使用しておらず、追加する予定もありません。これをシンプルに保つ必要があります。ポリフィルを追加して、finally()がEdgeで機能することを確認するにはどうすればよいですか?ありがとう!
これは、以下に詳述する動作に加えて、thenableの伝播 species
を処理する必要があります。
_Promise.prototype.finally = Promise.prototype.finally || {
finally (fn) {
const onFinally = value => Promise.resolve(fn()).then(() => value);
return this.then(
result => onFinally(result),
reason => onFinally(Promise.reject(reason))
);
}
}.finally;
_
この実装は finally()
の文書化された動作に基づいており、仕様に準拠している then()
に依存します。
finally
コールバックは引数を受け取りません。これは、promiseが実行されたか拒否されたかを判断する信頼できる手段がないためです。このユースケースは、拒否の理由やフルフィルメントの値を気にしない場合に使用するため、提供する必要はありません。
Promise.resolve(2).then(() => {}, () => {})
(undefined
で解決される)とは異なり、Promise.resolve(2).finally(() => {})
は_2
_で解決されます。同様に、
Promise.reject(3).then(() => {}, () => {})
(undefined
で満たされる)とは異なり、Promise.reject(3).finally(() => {})
は_3
_で拒否されます。注:
throw
コールバックのfinally
(または拒否されたpromiseを返す)は、throw()
の呼び出し時に指定された拒否理由。
そしてもちろん、同等の動作のデモ:
_const logger = (label, start = Date.now()) => (...values) => {
console.log(label, ...values, `after ${Date.now() - start}ms`);
};
const delay = (value, ms) => new Promise(resolve => {
setTimeout(resolve, ms, value);
});
// run test on native implementation
test('native');
// force Promise to use the polyfill implementation
Promise.prototype.finally = /* Promise.prototype.finally || */ {
finally (fn) {
const onFinally = value => Promise.resolve(fn()).then(() => value);
return this.then(
result => onFinally(result),
reason => onFinally(Promise.reject(reason))
);
}
}.finally;
// run test on polyfill implementation
test('polyfill');
function test (impl) {
const log = ordinal => state => logger(`${ordinal} ${impl} ${state}`);
const first = log('first');
// test propagation of resolved value
delay(2, 1000)
.finally(first('settled'))
.then(first('fulfilled'), first('rejected'));
const second = log('second');
// test propagation of rejected value
delay(Promise.reject(3), 2000)
.finally(second('settled'))
.then(second('fulfilled'), second('rejected'));
const third = log('third');
// test adoption of resolved promise
delay(4, 3000)
.finally(third('settled'))
.finally(() => delay(6, 500))
.then(third('fulfilled'), third('rejected'));
const fourth = log('fourth');
// test adoption of rejected promise
delay(5, 4000)
.finally(fourth('settled'))
.finally(() => delay(Promise.reject(7), 500))
.then(fourth('fulfilled'), fourth('rejected'));
}
_
_.as-console-wrapper{max-height:100%!important}
_
@ Bergi にこの回答についてのご意見をお寄せいただきありがとうございます。 彼の実装 を参照して、この投稿が役に立ったと思われる場合は、それも賛成投票してください。