我继承了一个应用程序,它可以扫描页面,查找数据属性,并相应地修改dom、添加处理程序等。
我被要求实现动态标记,发出ajax调用来获取json数据,然后使用工具栏根据返回的数据呈现新的html。
我需要告诉主应用程序,外部应用程序,直到所有的json调用都被解析后,它才会去寻找数据属性。
我应该设置什么样的模式才能做到这一点?
任何帮助都将不胜感激。
谢谢你,斯科特
更新
outer.js -扫描DOM,寻找要做的事情。
inner.js -发出0-9 ajax调用(取决于我所在的页面)。每个ajax调用都有一个.then()函数,该函数调用工具栏函数来编写标记。
如果我只有一个ajax调用,我可以将inner.js作为延迟传递回outer.js。然后,在ajax的.then()函数中,我只需调用inner.js.resolve()。
但是,如果我对9种可能的inner.js中的每一种都这样做,那么在#1运行之后,但在#2完成之前,就会解决这个问题。
我如何动态地设置outer.js用来等待直到它们都被解决的延迟数?
似乎不可能延迟绑定这样的数组:
在inner.js顶部:
var application = jQuery.Deferred();
var arrayOfAsync = [];
application.done(arrayOfAsync);然后,当在页面上找到jQuery选择器时,我可以做一个
arrayOfAsync.push(localPromise);但这似乎行不通..。应该这样吗?这将假定延迟()实际上只是保留一个正常数组,而这个数组可能不是.
发布于 2015-10-08 18:49:48
在这种情况下,你应该使用承诺。
假设您有您的车把模板:
<script id="PostsTempl" type="text/x-handlebars-template">
{{#each posts}}
<li class="item-handlebars">{{body}}</li>
{{/each}}
</script>其中应该包含一系列从web /web服务中获取的帖子。
在使用模板之前,您将编译它:
var myTemplate = Handlebars.compile($("#PostsTempl").html());现在我们需要一个函数来调用web /web服务并获取一些数据:
function fetchData()
{
var deferred = $.Deferred();
$.ajax({
type: 'GET',
dataType: 'json',
url: 'my/api/posts/1/20',
data: {},
success: function (jsonData) {
if (jsonData) {
deferred.resolve(jsonData);
} else {
deferred.reject('');
}
},
error: function (req, status, error) {
var errorMessage = (error.message) ? error.message : error;
deferred.reject(errorMessage);
}
});
return deferred.promise();
}我们将使用$.ajax来获取获取数据的。我们在这里定义了一个承诺:
var deferred = $.Deferred();当我们得到数据时,这个问题将被解决:
success: function (jsonData) {
if (jsonData) {
deferred.resolve(jsonData);
} else {
deferred.reject('');
}
},或者最终被拒绝如果没有数据的话。
return deferred.promise();会回报我们的承诺。
现在,我们可以调用解析承诺的函数,并反馈一些数据:
fetchData()
.then(function(data){
// console.log(data);
var posts = {posts: data};
$("#posts").append(myTemplate(posts));
return true;
})
.then(function(result){
goLookForDataAttributes();
})
.fail(function (reason) {
if (reason !== '') {
alert('Something went wrong:' + reason);
}
}); 当我们拿回数据后,我们将项目附加到我们的模板中:
.then(function(data){
// console.log(data);
var posts = {posts: data};
$("#posts").append(myTemplate(posts));
return true;
})完成所有操作后,我们在另一个.then()分支中调用另一个函数:
.then(function(result){
goLookForDataAttributes();
})承诺是可以锁链的。第二个.then()是在第一个执行之后调用的。
这是你需要的最后一点:
function goLookForDataAttributes()
{
$('#posts li.item-handlebars').each(function (index, item) {
$(item).addClass('big-font');
});
}这个小提琴可能对你有帮助。
在本例中,当handlebards呈现元素时,我解析这些帖子并添加一个类。
更新:
由于您正在调用web /web服务,所以可以并行执行承诺,等待所有ajax请求完成并执行最后一个方法。
为了简单起见,我将创建一个虚假的承诺(这应该是ajax请求):
function buildPromise(id)
{
var deferred = $.Deferred();
setTimeout(function(){
var data = {id: id, name: 'name: ' + id};
deferred.resolve(data);
}, 1000);
return deferred.promise();
}我将创建一个数组,比方说,10个承诺:
var promises = [];
for (var p = 0; p < 10; p++)
{
promises.push(buildPromise(p));
}现在,我将能够并行地执行所有这些承诺:
$.when.apply($, promises)
.then(function () {
for(var i = 0; i < arguments.length; i++) {
$('#content').append('<p>' + arguments[i].name + '</p>');
}
}).then(function(results) {
return finalPromise();
})
.then(function(result){
alert('success: ' + result.success);
alert('Finished');
});$.when.apply($, promises)并行地解析所有承诺,并在我们返回所有结果时返回。
结果可以在arguments中找到,并且可以使用数组arguments[x]的索引来读取。
当执行了所有ajax请求后,我们将调用finalPromise
function finalPromise()
{
var deferred = $.Deferred();
setTimeout(function(){
var data = { success: true };
deferred.resolve(data);
}, 1000);
return deferred.promise();
}finalPromise可能是一个常规函数,也没有任何承诺。
这就是它的样子。
当然,现在你必须使它适应你的情况。
https://stackoverflow.com/questions/33022854
复制相似问题