Запрос отложен для объединения вызовов

Имея следующие 3 функции:

var f1 = function(e) { setTimeout(function () { return e + 1;}, 1000); }
var f2 = function(e) { setTimeout(function () { return e + 5;}, 1000); }
var f3 = function(e) { setTimeout(function () { return e + 7;}, 1000); }

Как я могу объединить вызовы, используя jQuery.Deferred, так что мой вызов будет выглядеть так:

$.when(f1()).then(f2()).then(f3()).done(function(result){ /* I want it to be 13 when called with 0! */ });

а затем вызвать стек с 0 в качестве входного параметра?

Я сейчас использую вложенный ready: function(){} но хотел бы перейти к чему-то более управляемому.

Подводя итог, я ищу способ сложить произвольные сервисные вызовы так, чтобы они выполнялись в заданном порядке, и выходные данные каждой N-функции будут использоваться в качестве входных данных для N+1.

Я хочу сохранить свои функции плоскими и как можно более чистыми от кода jQuery. Было бы неплохо найти способ передать корневое значение хорошим способом, а не жестко кодировать его в самом вызове функции.

Я могу увидеть образец использования then в сочетании с несколькими аргументами, переданными в $.when(f1, f2, f3).then(result1, result2, result3) - но это не то, что я после.

Вот что у меня так далеко:

http://jsbin.com/yaqitagelazo/1/

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="scripts/external/jquery-2.1.1.min.js"></script>
</head>
<body>

    <script>
        $(function() {

            var first = function (e) {
                var d = $.Deferred();

                setTimeout(function () {

                    e = e + 1;
                    d.resolve(e);
                }, 1000);

                return d.promise();
            };

            var second = function (e) {
                var d = $.Deferred();

                e = e + 5;

                setTimeout(function () {

                    d.resolve(e);

                }, 1000);

                return d.promise();
            };

            // so far so good, passing 0 right in the call doesn't look good.
            // Q: how do I pass the value for the root function call?
            $.when(first(0)).done(function(result) { alert(result); }); 

            // Q: doesn't work at all returns on first return.
            $.when(first(0))
                .then(second())
                .done(function(result) {
                    alert(result);
                });
        });
    </script>


</body>
</html>

1 ответ

Решение

Пытаться

var _e = {
  e : 0
};

var f1 = function(e) { 
    return new $.Deferred(function(j) {
        _e.e = e + 1; 
        $.when(f2(5), f3(7))
        .done(function(n) {
            setTimeout(function() { 
                j.resolve(n)
            }, 1000)
        }); 
        return j.promise()
    }) 
};

var f2 = f3 = function(n) {
    _e.e = _e.e + n; 
    var dfd = new $.Deferred(); 
    setTimeout(function() { 
        dfd.resolve(_e.e)
    },1000); 
    return dfd.promise() 
};

f1(0).done(function(res) {
  console.log(res)
});

В качестве альтернативы

независимые функции

var _e = {
    e : 0 
};

var f1 = function() { 
  return new $.Deferred(function(dfd) { 
    setTimeout(function () { 
      _e.e = _e.e + 1; dfd.resolve(_e.e);
    }, 1000); 
    return dfd.promise()
  }); 
};

var f2 = function() { 
  return new $.Deferred(function(dfd) { 
    setTimeout(function () { 
      _e.e = _e.e + 5; dfd.resolve(_e.e);
    }, 1000); 
    return dfd.promise()
  }); 
};

var f3 = function() { 
  return new $.Deferred(function(dfd) { 
    setTimeout(function () { 
      _e.e = _e.e + 7; dfd.resolve(_e.e);
    }, 1000); 
    return dfd.promise()
  }); 
};

f1(), f2(), f3().done(function(res) {
  console.log(res)
})

Одиночная функция

var _e = {
    e : 0
};

var f1 = f2 = f3 = function(n) { 
  return new $.Deferred(function(dfd) { 
    setTimeout(function () { 
        _e.e = _e.e + n; dfd.resolve(_e.e);
    }, 3000); 
        return dfd.promise()
  }); 
};

f1(1), f2(5), f3(7).done(function(res) {
  console.log(res)
})
Другие вопросы по тегам