【发布时间】:2014-11-04 15:07:54
【问题描述】:
我正在尝试实现一个异步计算的 observable,如 show here。
我可以通过一个 ajax 调用成功地做到这一点。我目前面临的挑战是如何在循环中执行各种 ajax 调用,以异步方式构建数组,然后使用 jQuery Promise 将数组返回到我计算的可观察数组。
基本上,HTML 表单的工作方式如下:
- 这是一个学生课程表。
- 对于每一行,用户输入人员编号,然后在另一列输入以逗号分隔的课程 ID 列表。例如 100、200、300。
- 计算的 observable 的目的是存储一个数组 包含在第 2 步中输入的课程的课程详细信息。
- 通过为每个课程触发 ajax 调用并将 HTTP 响应存储在数组中来获取详细信息。
- 我不希望用户等待结果,因此是实现异步计算 observable 的原因。
我的问题:我在将最终数组的值返回到 observable 时遇到问题。它总是未定义的。 ajax 调用工作正常,但也许我仍然没有正确处理承诺。
这是我班级的代码:
function asyncComputed(evaluator, owner) {
var result = ko.observable(), currentDeferred;
result.inProgress = ko.observable(false); // Track whether we're waiting for a result
ko.computed(function () {
// Abort any in-flight evaluation to ensure we only notify with the latest value
if (currentDeferred) { currentDeferred.reject(); }
var evaluatorResult = evaluator.call(owner);
// Cope with both asynchronous and synchronous values
if (evaluatorResult && (typeof evaluatorResult.done == "function")) { // Async
result.inProgress(true);
currentDeferred = $.Deferred().done(function (data) {
result.inProgress(false);
result(data);
});
evaluatorResult.done(currentDeferred.resolve);
} else // Sync
result(evaluatorResult);
});
return result;
}
function personDetails(id, personNumber, courseIds) {
var self = this;
self.id = ko.observable(id);
self.personNumber = ko.observable(personNumber);
self.courseIds = ko.observable(courseIds);
// Computed property to extract PIC details for additional PICs.
// This is computed observable which returns response asynchronously
self.courseDetails = asyncComputed(function () {
var courseIdsArray = self.courseIds().split(",");
var arr = [];
var arr_promises = [];
function getCourseDetails(courseId) {
var dfrd = $.Deferred();
var content = {};
content.searchString = courseId;
var url = 'MyURL';
return $.ajax(url, {
type: 'POST',
dataType: 'json',
data: requestData, // content of requestData is irrelevant. The ajax call works fine.
processdata: true,
cache: false,
async: true,
contentType: "application/json"
}).done(function (data) {
arr.push(new PicDetails(data.GenericIdentifierSearchResult[0]));
}).fail(function () {
alert("Could not retrieve PIC details");
}).then(function () {
dfrd.resolve();
});
}
if (courseIdsArray.length > 0) {
$.each(courseIdsArray, function (index, courseId) {
if (courseId.length > 0) {
arr_promises.push(getCourseDetails(courseId));
}
});
};
$.when.apply($, arr_promises).done(function () {
return arr;
})
}, this);
}
【问题讨论】:
标签: javascript jquery arrays ajax knockout.js