Javascript 如何在 jQuery 1.8.x 中链接一系列延迟函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13651243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 12:35:28  来源:igfitidea点击:

How do I chain a sequence of deferred functions in jQuery 1.8.x?

javascriptasynchronousjquery-deferred

提问by camwest

Given these functions:

鉴于这些功能:

function func1() {
  var dfd = $.Deferred();

  setTimeout(function() {
    dfd.resolve('Password');
  }, 1000);

  return dfd.promise();
}

function func2(message) {
  var dfd = $.Deferred();

  setTimeout(function() {
    if (message == 'Password') {
      dfd.resolve('Hello World');
    }
   }, 1000);

  return dfd.promise();
}

I'd like to find a better way to do the following. Note this is using jQuery 1.8.x.

我想找到一种更好的方法来执行以下操作。请注意,这是使用 jQuery 1.8.x。

var promise = func1();

promise.done(function(message1) {

  var promise2 = func2(message1);

  promise2.done(function(message2) {
    alert(message2);
  });
});

Any ideas? I thought using jQuery #pipe or #then would work but I can't figure it out. Here is a fiddle to play around: http://jsfiddle.net/Z7prn/

有任何想法吗?我认为使用 jQuery #pipe 或 #then 会起作用,但我无法弄清楚。这是一个可以玩的小提琴:http: //jsfiddle.net/Z7prn/

回答by Felix Kling

It's not that complicated (either use .thenor .pipe, they are both the same since jQuery 1.8 I think).

它并没有那么复杂(无论是使用.then还是.pipe,我认为它们自 jQuery 1.8 以来都是相同的)。

func1().then(func2).done(function(message) {
    alert(message);
});

Since func2returns a new deferred object, the .donecallback is attached to that one instead.

由于func2返回一个新的延迟对象,因此.done回调将附加到该对象上。

DEMO

演示

回答by Fordi

I had a similar use case, so I think this should help you out.

我有一个类似的用例,所以我认为这应该对你有所帮助。

The following method will take an array of methods (which may or may not return Promises) and execute them in sequence, waiting until each deferred is complete before proceeding. Default behavior is to stop on failure; second argument lets you proceed whether the call fails or not.

下面的方法将采用一组方法(可能返回也可能不返回 Promise)并按顺序执行它们,等待每个 deferred 完成后再继续。默认行为是在失败时停止;无论调用是否失败,第二个参数都可以让您继续。

done/fail handler signatures are (Array<context>) Function (Array<Object{ rejected|resolved: arguments}>), where contextis the context of each resolveWith/rejectWith call, or the deferred in question, and argumentsis the argument set that was passed in the resolution / rejection.

done/fail 处理程序签名是 (Array< context>)Function(Array<Object{rejected|resolved: arguments}>),其中context是每个 resolveWith/rejectWith 调用的上下文,或者有问题的延迟,arguments是参数在决议/拒绝中通过的集合。

(function ($) {
    "use strict";
    var copy = function (a) {
        return Array.prototype.slice.call(a);
    };

    /**
        Handle a sequence of methods, stopping on failure by default
        @param Array<Function> chain    List of methods to execute.  Non-deferred return values will be treated as successful deferreds.
        @param Boolean  continueOnFailure   Continue executing even if one of the returned deferreds fails.
        @returns Deferred
     */
    $.sequence = function (chain, continueOnFailure) {
        var handleStep, handleResult,
            steps = copy(chain),
            def = new $.Deferred(),
            defs = [],
            results = [];
        handleStep = function () {
            if (!steps.length) {
                def.resolveWith(defs, [ results ]);
                return;
            }
            var step = steps.shift(),
                result = step();
            handleResult(
                $.when(result).always(function () {
                    defs.push(this);
                }).done(function () {
                    results.push({ resolved: copy(arguments) });
                }).fail(function () {
                    results.push({ rejected: copy(arguments) });
                })
            );
        };
        handleResult = continueOnFailure ?
                function (result) {
                    result.always(function () {
                        handleStep();
                    });
                } :
                function (result) {
                    result.done(handleStep)
                        .fail(function () {
                            def.rejectWith(defs, [ results ]);
                        });
                };
        handleStep();
        return def.promise();
    };
}(this.jQuery));

A simple example of use: http://jsfiddle.net/rG9rA/

一个简单的使用示例:http: //jsfiddle.net/rG9rA/

function func1() {
  var dfd = $.Deferred();

  setTimeout(function() {
    dfd.resolve('Password');
  }, 1000);

  return dfd.promise();
}

function func2(message) {
  var dfd = $.Deferred();

  setTimeout(function() {
    if (message == 'Password') {
      dfd.resolve('Hello World');
    }
   }, 1000);

  return dfd.promise();
}

    $.sequence([func1, func2, function () { alert('done'); }]);