Запрос отложен для объединения вызовов
Имея следующие 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)
})