首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jQuery异步编程模式?

jQuery异步编程模式?
EN

Stack Overflow用户
提问于 2015-10-08 18:00:03
回答 1查看 498关注 0票数 0

我继承了一个应用程序,它可以扫描页面,查找数据属性,并相应地修改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顶部:

代码语言:javascript
复制
var application = jQuery.Deferred();
var arrayOfAsync = [];
application.done(arrayOfAsync);

然后,当在页面上找到jQuery选择器时,我可以做一个

代码语言:javascript
复制
arrayOfAsync.push(localPromise);

但这似乎行不通..。应该这样吗?这将假定延迟()实际上只是保留一个正常数组,而这个数组可能不是.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-08 18:49:48

在这种情况下,你应该使用承诺。

假设您有您的车把模板:

代码语言:javascript
复制
<script id="PostsTempl" type="text/x-handlebars-template">
    {{#each posts}}
        <li class="item-handlebars">{{body}}</li>
    {{/each}}
</script>

其中应该包含一系列从web /web服务中获取的帖子。

在使用模板之前,您将编译它:

代码语言:javascript
复制
var myTemplate = Handlebars.compile($("#PostsTempl").html());

现在我们需要一个函数来调用web /web服务并获取一些数据:

代码语言:javascript
复制
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来获取获取数据的。我们在这里定义了一个承诺

代码语言:javascript
复制
var deferred = $.Deferred();

当我们得到数据时,这个问题将被解决:

代码语言:javascript
复制
success: function (jsonData) {
    if (jsonData) {
       deferred.resolve(jsonData);
    } else {
       deferred.reject('');
    }
},

或者最终被拒绝如果没有数据的话。

return deferred.promise();会回报我们的承诺。

现在,我们可以调用解析承诺的函数,并反馈一些数据:

代码语言:javascript
复制
  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);
        }
    }); 

当我们拿回数据后,我们将项目附加到我们的模板中:

代码语言:javascript
复制
.then(function(data){
    // console.log(data);
    var posts = {posts: data};
    $("#posts").append(myTemplate(posts));
    return true;
})

完成所有操作后,我们在另一个.then()分支中调用另一个函数:

代码语言:javascript
复制
   .then(function(result){
        goLookForDataAttributes();
    })

承诺是可以锁链的。第二个.then()是在第一个执行之后调用的。

这是你需要的最后一点:

代码语言:javascript
复制
function goLookForDataAttributes()
{
    $('#posts li.item-handlebars').each(function (index, item) {
        $(item).addClass('big-font');
    });
}

这个小提琴可能对你有帮助。

在本例中,当handlebards呈现元素时,我解析这些帖子并添加一个类。

更新:

由于您正在调用web /web服务,所以可以并行执行承诺,等待所有ajax请求完成并执行最后一个方法。

为了简单起见,我将创建一个虚假的承诺(这应该是ajax请求):

代码语言:javascript
复制
function buildPromise(id)
{
    var deferred = $.Deferred();

    setTimeout(function(){
        var data = {id: id, name: 'name: ' + id};
        deferred.resolve(data);
    }, 1000);

    return deferred.promise();
}

我将创建一个数组,比方说,10个承诺:

代码语言:javascript
复制
var promises = [];

for (var p = 0; p < 10; p++)
{
    promises.push(buildPromise(p));
}

现在,我将能够并行地执行所有这些承诺:

代码语言:javascript
复制
$.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

代码语言:javascript
复制
function finalPromise()
{
    var deferred = $.Deferred();

    setTimeout(function(){
        var data = { success: true };
        deferred.resolve(data);
    }, 1000);

    return deferred.promise();

}

finalPromise可能是一个常规函数,也没有任何承诺。

就是它的样子。

当然,现在你必须使它适应你的情况。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33022854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档