【问题标题】:Is this actually a js promise?这实际上是一个 js 承诺吗?
【发布时间】:2014-06-23 13:21:58
【问题描述】:

我在 javascript 模块中有这段代码(我正在使用 Require js 和 Knockout)

var getPersons = function(personsObservable) {
    personsObservable([]);
    var getOptions = {
        url: 'api/persons',
        type: 'GET',
        dataType: 'json'
    };

    return $.ajax(getOptions)
        .then(querySucceeded)
        .fail(queryFailed);

    function querySucceeded(data) {
        var persons = [];
        data.sort(sortPersons);
        data.forEach(function (item) {
            var p = new model.Person(item);
            persons.push(p);
        });

        personsObservable(persons);
    };
}

然后在另一个使用该模块的模块中,我这样称呼它:

function refresh() {
    return dataservice.getPersons(persons).then(dataservice.getTalks(talks));
};

正在 getTalks 数据服务模块中的另一个功能。

但我不确定结果是否会成为实际的承诺,即在我用 ajax 调用的结果填充人员之前,不会调用 getTalks。据我了解,调用 then 方法可以解决问题,对吗?

谢谢

更新:

所以在阅读了答案并进一步调查了我想出的这些承诺之后,不知道是否有意义

现在 getPersons 和 getTalks 不会填充 observable 而只是返回数组,刷新函数如下所示:

function refresh() {
    return $.when(dataservice.getPersons(persons), dataservice.getTalks(talks))
                .then(
                        //Success
                        function (personArgs, talksArgs) {
                            persons(personArgs);
                            talks(talksArgs);
                        },
                        //Failure
                        function(){
                            logger.log("There's been an error retrieving the data");
                        });
 };

TI 仍然需要此刷新返回一个承诺,因此仍然对此表示怀疑。

【问题讨论】:

  • 这个.then(dataservice.getTalks(talks)) 应该是.then(function() {return dataservice.getTalks(talks)})。您需要传递可以在将来执行的函数引用。您正在立即执行它并传递它的返回值。

标签: ajax promise knockout-2.0


【解决方案1】:

如果函数 getPersons 命名良好,那么它只会做(获取人员)而不是更多,并且对 personsObservable 的两次调用将在调用 getPersons 时进行。

getPersons 将因此压缩为:

var getPersons = function () {
    return $.ajax({//return here to make the make the result of the $.ajax().then() chain available at the point where getPersons() is called.
        url: 'api/persons',
        dataType: 'json'
    }).then(function (data) {
        //sortPersons is presumably defined in an outer scope
        return data.sort(sortPersons).map(function (item) {//return here to make the mapped array available as the promised result of getPersons.
            return new model.Person(item);//return here to push elements onto the mapped array
        });
    });
};

注意 - 为了保持简洁和高效,函数内不进行任何分配

并且会被调用,例如,如下:

persons([]);
getPersons().then(persons).fail(queryFailed);

整个promise链(简写)因此是$.ajax().then().then().fail();,但拆分后链中的前两个调用在getPersons内,这会返回一个适当的promise。

refresh 函数中使用$.when() 会使事情变得稍微复杂一些。将getTalks修改为与getPersons相同的方式,refresh可以写成如下:

function refresh () {
    persons([]);
    talks([]);//assumed
    return $.when(dataservice.getPersons(), dataservice.getTalks()).then(function (p, t) {
        persons(p);
        talks(t);
    }, function () {
        logger.log("There's been an error retrieving the data");
    });
};

【讨论】:

  • 感谢 Roamer,虽然我不需要在从承诺返回的参数中使用 [0],但它似乎工作正常,我发现调试,因为返回的数组正是人和谈话
  • 嗯,好的,在这种情况下,我最好编辑我的答案。 jQuery 的这一方面足以让任何人发疯。文档记录真的很差。
猜你喜欢
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2022-01-27
  • 1970-01-01
相关资源
最近更新 更多