我有以下代码:
$.when(multipleQueries(stateQueries, rowData))
.then(function (data) {
//do stuff with data - removed for brevity
multipleQueries函数如下:
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();
}
我遇到的问题是我传递了5个查询以执行到multipleQueries函数,但是在运行第一个查询后它正在调试调试器行 - 然后解析allQueriesMapped延迟然后它返回到do数据调用的东西,因为我没有收到我传入的5个queires中的所有数据,我没有看到预期的行为 - 是否有什么东西缺少我如何设置这些承诺?
注意 - 我尝试将调试器之前的.then更改为.done但是获得相同的行为,并尝试将调用代码更改为.done,如下所示,但同样也是如此。
$.when(multipleQueries(stateQueries, rowData))
.done(function (data) {
//do stuff with data - removed for brevity
**更新 - 执行查询功能在
之下function executeQuery(instanceInfo, query) {
return $.ajax({
url: instanceInfo.Url,
type: 'GET',
data: {
q: query,
succinct: true
},
processData: true
});
}
答案 0 :(得分:0)
正如liben-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();
}
但是那里有{strong>很多不必要地使用$.when
和new $.Deferred
(请参阅*** 1
条评论),您可以包装参数在数组中更简单(参见*** 2
注释:
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)
。
您也可以从早期转换为内置的promise语义而不是jQuery' s Deferred
中受益:
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
对于处理promises数组非常有用。但是请确保您使用的是最新的jQuery,早期版本的Deferred并没有与真正的承诺进行适当的互操作。