构建一种在画布导航中为Web应用程序创建标记的方法。我正在对另一个返回父菜单节点的子节点的服务进行异步回调(参见下面的代码):
function GenerateMarkup(Terms, n) {
var termsEnum = Terms.getEnumerator();
var html = "<ul>";
// Process top level terms
while (termsEnum.moveNext()) {
var currentTerm = termsEnum.get_current();
html += "<li>"
if (currentTerm.get_termsCount() > 0) {
var childcall = function() {
var deferred = $.Deferred();
html += "<a href=\"#\">" + currentTerm.get_name() + "<br><span>" + currentTerm.get_description() + "</span></a>";
SPTermStore.GetTermsFromTermSet(currentTerm).then(function(termSet) {
if (typeof termSet !== undefined) {
deferred.resolve(GenerateMarkup(termSet, n++));
}
else
deferred.reject("something bad happened");
});
return deferred.promise();
};
$.when(childcall()).done(function(markup) {
html += markup;
});
} // end if
else
html += "<a href=\"#\">" + currentTerm.get_name() + "</a>";
html += "</li>"
} // end while
html += "</ul>";
console.log("GenerateMarkup (" + n + "): " + html);
return html;
} // end function
问题是标记生成的顺序不正确;在正常的同步中,GenerateMarkup的递归调用将完成,但在这种情况下,我试图等待返回的promise(即对GenerateMarkup的调用完成),所以我可以追加html。这个想法是在迭代过程中,顶级节点将处理其子节点等。
如果我查看console.log输出,这就是我得到的;问题是下面列出的第一个标记是返回页面的内容,而不是下面的组合。
GenerateMarkup (0): <ul><li><a href="#">About<br><span>Our Company</span></a></li><li><a href="#">Portfolio<br><span>Our Properties</span></a></li><li><a href="#">Corporate Responsibility<br><span>Our Committment</span></a></li></ul>
GenerateMarkup (0): <ul><li><a href="#">Careers</a></li><li><a href="#">Core Values</a></li><li><a href="#">Governance</a></li><li><a href="#">History</a></li></ul>
GenerateMarkup (1): <ul><li><a href="#">Core Market Strategy</a></li><li><a href="#">Our Properties</a></li></ul>
GenerateMarkup (2): <ul><li><a href="#">Community Involvement</a></li><li><a href="#">CSR Report</a></li><li><a href="#">Diversity</a></li><li><a href="#">Sustainability</a></li></ul>
任何帮助都将不胜感激。
答案 0 :(得分:1)
Promise是异步的,所以他们不能保证按照他们承诺的顺序返回。
如果排序很重要,请考虑将promises链接起来,以便它们按照您期望的顺序执行。 Promise.then can be chained.
答案 1 :(得分:0)
一种可能性是遍历termsenumerator,并将它们加载到延迟数组中。然后应用$ when。见下面的示例:
var deferreds = [];
for (var i = 0; i<termsenumerator; i++) {
deferreds.push(Grab data you want and push it into this array);
}
//Now that we have all the results... (deferred), process these.
$.when.apply($, deferreds).done(function () {
var resultdata = [];
for (var i = 0; i < arguments.length; i++) {
var daydata = arguments[i][2];
applymarkupWData(resultdata.responseJSON.d,i);
};
});