【问题标题】:How to make a jQuery promise from another promise如何从另一个承诺做出 jQuery 承诺
【发布时间】:2013-11-09 11:39:58
【问题描述】:

我正在编写一个基于 $.getJSON() 和 HTML5 的 sessionStorage 作为缓存的基本存储库。

当第一次请求数据时,存储库会从 Web 服务中读取数据并将其存储在 sessionStorage 中,以便下次从缓存中读取数据。以下是我使用任务实体的存储库的代码:

Storage.prototype.setObject = function (key, value) { this.setItem(key, JSON.stringify(value)); };
Storage.prototype.getObject = function (key) { return JSON.parse(this.getItem(key)); };

var repository = function () {
    var getTasks = function () {
        if (sessionStorage.getObject("Tasks") {
            return $.Deferred().resolve(sessionStorage.getObject("Tasks")).promise();
        }
        else {
            return $.getJSON("/gettasks").done(function (data) {
                sessionStorage.setObject("Tasks", data);
            }).promise();
        }
    }

    var findTask = function (id) {
        var item;
        return getTasks().done(function (tasks) {
            for(var t in tasks)
                if(tasks[t].id == id)
                    item = tasks[t];
        }).resolve(item);
    }

    return {
        getTasks: function () { return getTasks(); },
        findTask: function (id) { return findTask(id); }
    };
}();

getTasks 的返回类型无论如何都是一个 jQuery 承诺(无论是从 Web 服务还是从缓存中读取数据)。这是我的客户端代码中存储库的用法:

repository.getTasks().done(function (tasks) {
    // display list
}).fail(function(err) {
    // show error
});

现在我想要的是另一个函数,它可以通过相同的方式通过它的 id 来查找任务。所以我需要 findTask 函数来调用 getTasks 函数,然后尝试通过 id 在列表中查找任务项。我现在的问题是在承诺中返回单个任务项。但是 find 方法现在返回整个列表(基本上它返回 getTasks 函数的结果)。但我需要它,就像我阅读下面的列表一样:

repository.findTask(765).done(function (task) {
    // display task item 765
}).fail(function(err) {
    // show error
});

非常感谢。

【问题讨论】:

    标签: jquery promise resolve


    【解决方案1】:

    尝试使用deferred.then

    var findTask = function (id) {
        return getTasks().then(function (tasks) {
            for (var t in tasks) {
                if (tasks[t].id == id) {
                    return tasks[t];
                }
            }
        })
    }
    

    演示:Fiddle

    注意:这种方法的一个问题是即使未找到该项目,也会调用完成回调。

    另一种解决方案是创建自己的 deferred like

    var findTask = function (id) {
        var deferred= jQuery.Deferred();
        getTasks().done(function (tasks, status, xhr) {
            for (var t in tasks) {
                if (tasks[t].id == id) {
                    deferred.resolveWith(this, [tasks[t]]);
                    return;
                }
                deferred.reject(xhr, 'error', 'NOT FOUND');
            }
        }).fail(function(xhr, status, textStatus){
            deferred.reject.apply(deferred, arguments);
        });
    
        return deferred.promise();
    }
    

    演示:Fiddle

    【讨论】:

    • 非常感谢。是的然后工作。我会找到完成回调的方法。再次感谢,对不起,我没有足够的声誉来投票:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多