jQueryの延期された配列をどのように使用して作業しますか?
-
28-10-2019 - |
質問
データを特定の順序でロードする必要があるアプリケーションがあります:ルートURL、次にスキーマ、次にさまざまなデータオブジェクトのスキーマとURLを使用してアプリケーションを初期化します。ユーザーがアプリケーションをナビゲートすると、データオブジェクトがロードされ、スキーマに対して検証され、表示されます。ユーザーがデータを粗くすると、スキーマはファーストパス検証を提供します。
初期化に問題があります。 ajax呼び出しを使用して、ルートオブジェクト$ .when()を取得し、各スキーマオブジェクトに1つの約束を作成します。それはうまくいきます。コンソールにフェッチが表示されます。
次に、すべてのスキーマのフェッチが表示されるため、各$ .ajax()は動作します。 fetchschemas()は実際に約束の配列を返します。
ただし、その最終的な()句が発射されることはなく、「done」という言葉はコンソールに表示されません。 jQuery-1.5のソースコードは、「null」が$ .when.apply()に渡すオブジェクトとして許容できることを暗示しているようです。渡された。
これはfutures.jsを使用して機能しました。このようでなければ、jQueryの延期をどのように管理する必要がありますか?
var fetch_schemas, fetch_root;
fetch_schemas = function(schema_urls) {
var fetch_one = function(url) {
return $.ajax({
url: url,
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
return $.map(schema_urls, fetch_one);
};
fetch_root = function() {
return $.ajax({
url: BASE_URL,
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
$.when(fetch_root()).then(function(data) {
var promises = fetch_schemas(data.schema_urls);
$.when.apply(null, promises).then(function(schemas) {
console.log("DONE", this, schemas);
});
});
解決
あなたが探しています
$.when.apply($, promises).then(function(schemas) {
console.log("DONE", this, schemas);
}, function(e) {
console.log("My ajax failed");
});
これも機能します(ある程度の仕事のために、壊れたajaxを修正しません):
$.when.apply($, promises).done(function() { ... }).fail(function() { ... });`
あなたは合格したいです $
それ以外の null
となることによって this
中身 $.when
指します jQuery
. 。ソースにとっては問題ではないはずですが、通り過ぎるよりはましです null
.
それらを置き換えることにより、すべての$ .ajaxを模倣しました $.when
とサンプル 作品
したがって、Ajaxリクエストの問題であるか、Fetch_schemasに合格します。
他のヒント
上記の回避策(ありがとう!)は、延期されたオブジェクトを延期されたオブジェクトを取り戻す問題に適切に対処していません resolve()
jqueryが呼び出すため done()
と fail()
配列ではなく、個々のパラメーターを使用したコールバック。つまり、を使用する必要があります arguments
擬似アレイは、延期の配列によって返されたすべての解決/拒否されたオブジェクトを取得するために、ugいものです。
$.when.apply($, promises).then(function() {
var schemas=arguments; // The array of resolved objects as a pseudo-array
...
};
延期された配列を渡したので、一連の結果を取り戻すのはいいことです。擬似アレイの代わりに実際の配列を取り戻すこともできます。 Array.sort()
.
これが触発されたソリューションです when.js's when.all()
これらの問題に対処する方法:
// Put somewhere in your scripting environment
if (jQuery.when.all===undefined) {
jQuery.when.all = function(deferreds) {
var deferred = new jQuery.Deferred();
$.when.apply(jQuery, deferreds).then(
function() {
deferred.resolve(Array.prototype.slice.call(arguments));
},
function() {
deferred.fail(Array.prototype.slice.call(arguments));
});
return deferred;
}
}
これで、延期/約束の配列を渡すだけで、コールバックで解決/拒否されたオブジェクトの配列を取り戻すことができます。
$.when.all(promises).then(function(schemas) {
console.log("DONE", this, schemas); // 'schemas' is now an array
}, function(e) {
console.log("My ajax failed");
});
JavaScriptのES6バージョンを使用している場合、オブジェクトの配列をコンマ分離引数に変換するスプレッドオペレーター(...)があります。
$.when(...promises).then(function() {
var schemas=arguments;
};
ES6スプレッドオペレーターの詳細 https://developer.mozilla.org/en-us/docs/web/javascript/reference/operators/spread_operator ここで見つけてください
このコードを使用すると拡張されます。
var rawWhen = $.when
$.when = function(promise) {
if ($.isArray(promise)) {
var dfd = new jQuery.Deferred()
rawWhen.apply($, promise).done(function() {
dfd.resolve(Array.prototype.slice.call(arguments))
}).fail(function() {
dfd.reject(Array.prototype.slice.call(arguments))
})
return dfd.promise()
} else {
return rawWhen.apply($, arguments)
}
}