楽しい/勉強のために私はPromiseを拡張したいと思っていましたが、標準的な古い構文ではできないという、信じられないほど知名度の高い人たちがstackoverflowで見つけました。しかし私はとにかく欲しかったので、Promiseオブジェクトを作成し、他の人が古いES6以外の構文を使用して継承できるようにする独自のIPromiseクラスを作成することを考えました。これは継承可能な約束ですか?
私は、この実装が組み込みPromiseが直接継承可能な宇宙とどのように違うのか知りたいです。誰かが洞察力を持っている場合、組み込みPromiseの実装者は古い構文で継承を許可しません。
// Inheritable Promise
IPromise = function(executor) {
this.promise = new Promise(executor);
};
IPromise.prototype = Object.create(Promise.prototype);
IPromise.prototype.constructor = IPromise;
IPromise.prototype.catch = function(fail) {
return this.promise.catch(fail);
}
IPromise.prototype.then = function(success, fail) {
return this.promise.then(success, fail);
};
// Usage
// No different to builtin Promsise
(new IPromise(function(resolve, reject) { return resolve(true); }))
.then(function(response) {
console.log('IPromise then is like Promise then', response);
})
.catch(function(error) {
console.log('IPromise catch is like Promise catch', error);
});
はここですべての要求にかかわらず、それらのいずれかが失敗するかどうかを完了するのを待って、バッチAJAXのためにそれを拡張する例を示します
は、ここに私の拡張/継承IPromiseクラスです。組み込み機能とは少し異なります。
// Inheriting
// You can inherit from IPromise like you would any normal class.
BatchAjax = function(queries) {
var batchAjax = this;
this.queries = queries;
this.responses = [];
this.errorCount = 0;
IPromise.call(this, function(resolve, reject) {
batchAjax.executor(resolve, reject);
});
};
BatchAjax.prototype = Object.create(IPromise.prototype);
BatchAjax.prototype.constructor = BatchAjax;
BatchAjax.prototype.executor = function(resolve, reject) {
var batchAjax = this;
$.each(this.queries, function(index) {
var query = this;
query.success = function (result) {
batchAjax.processResult(result, index, resolve, reject);
};
query.error = function (jqXhr, textStatus, errorThrown) {
batchAjax.errorCount++;
var result = {
jqXhr: jqXhr, textStatus: textStatus, errorThrown: errorThrown
};
batchAjax.processResult(result, index, resolve, reject);
};
$.ajax(query);
});
};
BatchAjax.prototype.processResult = function(result, index, resolve, reject) {
this.responses[index] = result;
if (this.responses.length === this.queries.length) {
if (this.errorCount === 0) {
resolve(this.responses);
} else {
reject(this.responses);
}
}
};
// Usage
// Inheriting from IPromise is boring, which is good.
var baseUrl = 'https://jsonplaceholder.typicode.com';
(new BatchAjax([{url: baseUrl + '/todos/4'}, {url: baseUrl + '/todos/5'}]))
.then(function(response) {console.log('Yay! ', response);})
.catch(function(error) {console.log('Aww! ', error);});
私はちょうど学んでいるが、これは有用ではなく、面白いことを心に留めておいてください。しかし、残酷な批判をお寄せください、私はこれが愚かなことであるという考えに公開しています:)
すべてのコードを見て、ごめんなさい!
編集:元々私が約束を延長しようとしていたところです:Extending a Promise in javascript。 PromiseコンストラクタはPromise(私が思う)ではないものを初期化していることに気づいたら、Typeエラーをスローするため、古い構文では動作しないようです。
edit2:jfriend00さんのコメントは興味深いものです。どのようなIPromise.then戻す必要がありますか?現時点ではそれは単なる約束ですが、それはIPromiseであるべきですか?
IPromise.prototype.then = function(success, fail) {
this.promise.then(success, fail);
return new IPromise(whatGoesHere?);
};
または、それから継承したクラスのインスタンス。
IPromise.prototype.then = function(success, fail) {
this.promise.then(success, fail);
return new this.constructor(whatGoesHere?);
};
これを返すだけでよいですか?
IPromise.prototype.then = function(success, fail) {
this.promise.then(success, fail);
return this;
};
私はPromise.thenがPromiseを返すと知っていますが、Promiseがセットアップされているか、動作するとは思われません。だからこそ私はこの問題を避け、プロミスをこれから返送しました。他の賢明な解決法はありますか?
"これは標準の古い構文ではできません" – tommybananas
あなたはあなたができなかったと言われた質問にリンクすることもできます。いくつかのプログラミング言語では、 "I"接頭辞は具体的なクラスではなくインタフェースを示すために使用されています。その質問の命名は、一見、それらの人々のために混乱するかもしれません。 –
@tommybananasそれは母国語のタイプなので、 '__proto__'を使ってハックせずに' Array'や 'Error'を拡張できないように、' class'構文(ES5はない)で拡張することしかできません。 – loganfsmyth