您应该在这种情况下使用promise。
比方说,你有你的车把模板:
<script id="PostsTempl" type="text/x-handlebars-template">
{{#each posts}}
<li class="item-handlebars">{{body}}</li>
{{/each}}
</script>
应装满了一系列从Web API/web服务获取职位。
您将编译模板使用前:
var myTemplate = Handlebars.compile($("#PostsTempl").html());
现在,我们需要一个函数,它会调用web API/web服务,并会fetche一些数据:
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
至GET的数据。我们已经确定这里promise:
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');
});
}
这fiddle可能会帮助你。
在这个例子中,我解析帖子并添加一个类,当handlebards已呈现元素。
UPDATE:
既然你调用Web API/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)
RESOLV将所有承诺一起并行,并在我们收回所有结果时返回。
结果可以在arguments
中找到,并可以使用数组arguments[x]
的索引读取。
当所有Ajax请求都被执行,我们将调用finalPromise
:
function finalPromise()
{
var deferred = $.Deferred();
setTimeout(function(){
var data = { success: true };
deferred.resolve(data);
}, 1000);
return deferred.promise();
}
finalPromise
可能是一个普通的功能,没有承诺,也是如此。
This就是它的样子。
当然现在你必须适应你的情况。
这是很多令人困惑的输入。请问一个简短的简洁问题(如此处所述:[问]],并最好添加一些*最小*代码来演示您的结构。 – Amit
许多方法来做到这一点...取决于用例一点。需要更多关于ajax的详细信息......它是在一个循环中还是只有几个已知的调用等 – charlietfl
这取决于我所在的页面。我正在使用jQuery来搜索页面,看看是否有什么需要动态内容。每个找到的元素都独立于其他元素运行。 – Scott