如何执行javascript顺序延迟?

时间:2015-05-13 02:46:17

标签: jquery jquery-deferred

我想知道是否有办法按顺序和有条件地执行延期任务。也就是说,我想按顺序执行一些异步任务,其中我只执行下一个异步任务,具体取决于前一个的结果。承诺链的结果应该是最后执行的。

任何想法如何用Jquery推迟补丁。

编辑:

在我理解ajax正确调用之前,我开始使用以下代码来验证某个值是否与另一个值的相关值无关。

function findBroaderOrNarrowerConceptInFieldSelectedList(field, value) {

    var intputfields = $("#instance_" + field + "_wrapper" + " .ds-authority-value")

    if (intputfields.length == 0)
        return undefined;

    //go over each input field and retreive the value

    for (var i = 0; i < intputfields.length; i++) {
        //check if our value is in the broader concepts of the input field concept
        //if true return the wrapper element, if false next steps
        if (is_broader_concept(value.id, $(intputfields[i]).attr('value'))) {

            var WrapperdivId = "#" + $(intputfields[i]).attr('name').replace("_authority", "") + "_wrapper";

            return $($(WrapperdivId)[0]);
        }
        //check if our value is in the narrower concepts of the input field concept
        //if true return the wrapper element
        if (is_narrower_concept(value.id, $(intputfields[i]).attr('value'))) {

            var WrapperdivId = "#" + $(intputfields[i]).attr('name').replace("_authority", "") + "_wrapper";

            return $($(WrapperdivId)[0]);
        }
    }

    return undefined
}

问题是我的is_broader_concept看起来像这样:

function is_broader_concept(broaderuri, concepturi) {

    return getBroaderConcepts(concepturi).then(function(data, textStatus, jqXHR ) {

        var broaders = data

        if (broaders.length == 0)
            return false;

        for (var i = 0; i < broaders.length; i++) {

            if (broaders[i].uri == broaderuri)
                 return true;
        }
    });
}

现在我已经了解了延迟和承诺(不是因为我在scala(承诺和未来)中这么做了),我想调整我的第一个方法来处理延迟。但是,我没有看到任何可以帮助我轻松实现我想要的结构。

EDIT2:

我找到了以下的lib,如果您无关紧要启动许多并行任务,这是非常好的。事实上,它可以在成功的第一个回归。它是When的修改。虽然我觉得不必打电话给所有人都很好

https://github.com/terrycojones/jquery-when2

EDIT3:

我正在寻找一个没有错误的lib,可以执行https://codereview.stackexchange.com/questions/38420/sequential-function-call-in-javascriptConditionals on a chained deferred in jquery

之类的操作
  

EDIT4:根据@ Roamer-1888的回复进行更新

正确的is_broader并且更窄,适用于他的解决方案

function is_broader_concept_Promise(broaderuri, field) {

    var uri = field.value.substr(field.value.indexOf("http://"));

    return getBroaderConcepts(uri).then(function(data, textStatus, jqXHR ) {

        var broaders = data;

        if (broaders.length == 0)
            return $.Deferred( function( d){ d.reject(); }).promise();

        for (var i = 0; i < broaders.length; i++) {

            if (broaders[i].uri == broaderuri)
                return field;
        }
        return $.Deferred( function( d){ d.reject(); }).promise();
    });
}

function is_narrower_concept_Promise(narroweruri, field) {

    var uri = field.value.substr(field.value.indexOf("http://"));

    return getNarrowerConcepts(uri).then(function(data, textStatus, jqXHR ) {

        var narrowers = data;

        if (narrowers.length == 0)
            return $.Deferred( function( d){ d.reject(); }).promise();

        for (var i = 0; i < narrowers.length; i++) {

            if (narrowers[i].uri == narroweruri)
                return field;
        }
        return $.Deferred( function( d){ d.reject(); }).promise();
    });
}

非常感谢,

M

PS:我在一个月前开始使用jQuery。

3 个答案:

答案 0 :(得分:2)

只有在任务成功时才会触发.done()处理程序,因此您可以使用这样的嵌套done()处理程序:

step1().done(function() {
    step2().done(function() {
        step3().done(function() {
            // etc.
        });
    });
});

(其中step1()step2()step3()返回延迟对象)

如果要创建自己的延迟对象,可以调用deferred.resolve()表示任务成功,或deferred.reject()表示失败。

有关详细信息,请参阅jQuery.Deferred()文档。

答案 1 :(得分:1)

用简明的语言,目标可归纳如下:

  

“在循环的每个转弯处,如果没有发现更广泛的概念NOR(一个更窄的概念)(异步),那么继续测试,否则就会脱离循环”。

在同步代码中,这将是微不足道的,但在异步世界中有一些可以跳过的环节。特别是,jQuery不为异步NOR提供语法糖。但是,我们可以使用自定义jQuery.when_none()方法的形式编写一个:

jQuery.when_none = function() {
    //if all input-promises reject, then fulfil.
    //if any input-promise fulfills, then reject.
    var promises = $.map(arguments, function(p) {
        return $.Deferred(function(dfrd) {
            p.then(dfrd.reject, dfrd.resolve);//resolve/reject inversion
        }).promise();
    });
    return $.when.apply(null, promises);
};

接下来,修改is_broader_concept()(和is_narrower_concept())以返回将被解析/拒绝的承诺,而不是将使用布尔值true / false(还有其他微小更改)解析的承诺:< / p>

function is_broader_concept(uri, fld) {
    return getBroaderConcepts(fld.value).then(function(data) {
        if(data.indexOf(uri) > -1) {
            return fld; // The success state will be inverted by $.when_none(), and the rest of the .then() chain will be bypassed
        } else {
            return $.Deferred().reject().promise(); // The fail state will be inverted by $.when_none(), permitting the next step of the .then() chain.
        }
    });
}

最后,在findBroaderOrNarrowerConceptInFieldSelectedList()

  • 通过利用.then()循环遍历“.ds-authority-value”字段来构建.reduce()链。
  • 使用cutom方法$.when_none()实现所需的NOR逻辑以控制promise链。
function findBroaderOrNarrowerConceptInFieldSelectedList(field, value) {
    return $("#instance_" + field + "_wrapper").find(".ds-authority-value").get().reduce(function(promise, fld) {
        return promise.then(function() {
            return $.when_none(
                is_broader_concept(value.id, fld),
                is_narrower_concept(value.id, fld)
            );
        });
    }, $.when()).then(function() {
        /* success: ie "not found", so reinvert the logic to force down the fail path */
        return $.Deferred().reject(value.id + ' is neither broader-concept nor narrower-concept.');
    }, function(fld) {
        /* fail: ie "found", so reinvert the logic to force down the success path */
        return $.when($('#' + fld.name.replace('_authority', '') + '_wrapper')); // $(fld) ???
    });
}

实现NOR逻辑可能有一种更简单的方法,但我现在想不到它。

答案 2 :(得分:0)

什么时候-JJ会做的恰到好处。这就是我在寻找的东西

https://github.com/cujojs/when/blob/master/docs/api.md#api

相关问题