Как указали freedomn-m и charlietfl, этот then
находится не в том месте (см. ***
комментарий):
function multipleQueries(queriesToExecute, rowData) {
var allQueriesMapped = $.Deferred();
// If a single query has been provided, convert it into an array
if (Array.isArray(queriesToExecute) === false) {
queriesToExecute = [].concat(queriesToExecute);
}
// Create a function for each region to run the query.
$.when.apply($, $.map(queriesToExecute, function(query) {
// Execute the query in the region
return $.when(executeQuery(query.InstanceInfo, query.Query)).then(function(data) {
var isDataMapped = $.Deferred();
var mappedData = [];
// Perform some data transformation
$.when.apply($, $.map(data.results, function(value) {
var properties = value.succinctProperties;
//code removed for brevity
return $.when(mapData(properties)).then(function(mappedRow) {
if (mappedRow) {
mappedData.push(mappedRow);
}
});
})).then(function() {
isDataMapped.resolve({
results: mappedData,
numItems: mappedData.length
});
});
return isDataMapped.promise();
}).then(function(data) { // ***
debugger; // ***
allQueriesMapped.resolve(data); // ***
});
}));
return allQueriesMapped.promise();
}
Он внутри map
, когда он должен быть снаружи:
function multipleQueries(queriesToExecute, rowData) {
var allQueriesMapped = $.Deferred();
// If a single query has been provided, convert it into an array
if (Array.isArray(queriesToExecute) === false) {
queriesToExecute = [].concat(queriesToExecute);
}
// Create a function for each region to run the query.
$.when.apply($, $.map(queriesToExecute, function(query) {
// Execute the query in the region
return $.when(executeQuery(query.InstanceInfo, query.Query)).then(function(data) {
var isDataMapped = $.Deferred();
var mappedData = [];
// Perform some data transformation
$.when.apply($, $.map(data.results, function(value) {
var properties = value.succinctProperties;
//code removed for brevity
return $.when(mapData(properties)).then(function(mappedRow) {
if (mappedRow) {
mappedData.push(mappedRow);
}
});
})).then(function() {
isDataMapped.resolve({
results: mappedData,
numItems: mappedData.length
});
});
return isDataMapped.promise();
});
})).then(function(data) {
debugger;
allQueriesMapped.resolve(data);
});
return allQueriesMapped.promise();
}
Но есть много ненужного использования $.when
и new $.Deferred
там (см. *** 1
комментарии), и вы можете гораздо проще упаковать свой параметр в массив (см. * 1015) * комментарий:
function multipleQueries(queriesToExecute, rowData) {
// If a single query has been provided, convert it into an array
if (Array.isArray(queriesToExecute) === false) {
queriesToExecute = [queriesToExecute]; // *** 2
}
// Create a function for each region to run the query.
return $.when.apply($, $.map(queriesToExecute, function(query) { // *** 1
// Execute the query in the region
return executeQuery(query.InstanceInfo, query.Query).then(function(data) { // *** 1
var mappedData = [];
// Perform some data transformation
return $.when.apply($, $.map(data.results, function(value) {
var properties = value.succinctProperties;
//code removed for brevity
return mapData(properties).then(function(mappedRow) { // *** 1
if (mappedRow) {
mappedData.push(mappedRow);
}
});
})).then(function() {
return {
results: mappedData,
numItems: mappedData.length
};
});
});
}));
}
Если у вас уже есть обещание, вам больше не нужно создавать новое с помощью new
; просто используйте тот, который возвращается then
. Кроме того, когда у вас уже есть обещание, вам больше не нужно использовать $.when(thePromise)
.
Вам также может быть полезно перейти на встроенную семантику обещаний вместо раннего Deferred
jQuery:
function multipleQueries(queriesToExecute, rowData) {
// If a single query has been provided, convert it into an array
if (Array.isArray(queriesToExecute) === false) {
queriesToExecute = [queriesToExecute];
}
// Create a function for each region to run the query.
return Promise.all(queriesToExecute.map(function(query) {
// Execute the query in the region
return executeQuery(query.InstanceInfo, query.Query).then(function(data) {
return Promise.all(data.results.map(function(value) {
var properties = value.succinctProperties;
//code removed for brevity
return mapData(properties);
}).then(function(mappedData) {
mappedData = mappedData.filter(Boolean); // Remove the falsy ones from `mapData`
return {
results: mappedData,
numItems: mappedData.length
};
});
});
}));
}
Promise.all
очень полезен для работы с массивами обещаний. Но убедитесь, что вы используете новейший jQuery, более ранние версии Deferred не взаимодействовали должным образом с реальными обещаниями. Я не знаю (и не могу сразу найти), когда это было исправлено.