jQuery promise를 사용하여 3 개의 비동기 호출을 어떻게 연결합니까?
동기식으로 수행해야하는 세 개의 HTTP 호출이 있으며 한 호출에서 다른 호출로 데이터를 어떻게 전달합니까?
function first()
{
ajax()
}
function second()
{
ajax()
}
function third()
{
ajax()
}
function main()
{
first().then(second).then(third)
}
두 기능에 대해 지연을 사용하려고 시도했고 부분적인 해결책을 찾았습니다. 세 가지 기능으로 확장 할 수 있습니까?
function first() {
var deferred = $.Deferred();
$.ajax({
"success": function (resp)
{
deferred.resolve(resp);
},
});
return deferred.promise();
}
function second(foo) {
$.ajax({
"success": function (resp)
{
},
"error": function (resp)
{
}
});
}
first().then(function(foo){second(foo)})
각각의 경우에서 반환 한 jqXHR 객체를 반환합니다 $.ajax().
이러한 개체는 Promise와 호환되므로 .then()/ .done()/ .fail()/ 로 연결할 수 있습니다 .always().
.then() 이 경우 질문에서와 같이 정확히 원하는 것입니다.
function first() {
return $.ajax(...);
}
function second(data, textStatus, jqXHR) {
return $.ajax(...);
}
function third(data, textStatus, jqXHR) {
return $.ajax(...);
}
function main() {
first().then(second).then(third);
}
인수 data, textStatus그리고 jqXHR으로부터 발생하는 $.ajax()즉, 이전 함수 호출. first()피드 second()및 second()피드 third().
DEMO ($.when('foo')대신 이행 된 약속을 전달하기 위해$.ajax(...)).
jQuery와 함께 promise를 사용할 때 실제로 훨씬 더 쉬운 접근 방식이 있습니다. 다음을 살펴보십시오.
$.when(
$.ajax("/first/call"),
$.ajax("/second/call"),
$.ajax("/third/call")
)
.done(function(first_call, second_call, third_call){
//do something
})
.fail(function(){
//handle errors
});
모든 호출을 $ .when (...) 호출에 연결하고 .done (...) 호출에서 반환 값을 처리하기 만하면됩니다.
원하는 경우 둘러보기 : http://collaboradev.com/2014/01/27/understanding-javascript-promises-in-jquery/
답장하기에는 꽤 늦었지만 대답에는 체인에 대한 간단한 코드가 누락되어 있습니다. 이벤트 체인은 jquery의 promise 지원으로 매우 간단합니다. 연결을 위해 다음을 사용합니다.
$.ajax()
.then(function(){
return $.ajax() //second ajax call
})
.then(function(){
return $.ajax() //third ajax call
})
.done(function(resp){
//handle final response here
})
복잡한 for 루프 나 중첩 된 콜백이 없어 간단합니다.
그것보다 훨씬 간단합니다.
$.ajax 이미 promise (Deferred 객체)를 반환하므로 간단히 작성할 수 있습니다.
function first() {
return $.ajax(...);
}
보다 기능적인 방식으로 작성할 수 있습니다.
[function() { return ajax(...)}, function(data) { return ajax(...)}]
.reduce(function(chain, callback) {
if(chain) {
return chain.then(function(data) { return callback(data); });
} else {
return callback();
}
}, null)
여기서 좋은 해결책을 찾았 습니다. jQuery 1.8.x에서 지연된 함수 시퀀스를 어떻게 연결합니까?
그리고 여기에 비슷한 접근 방식의 내 자신의 구현이 있습니다. 반환 된 promise 객체에 대한«progress update»로 각 메소드의 결과를 브로드 캐스트합니다.
$.chain = function() {
var defer = $.Deferred();
var funcs = arguments;
var left = funcs.length;
function next(lastResult) {
if(left == 0) {
defer.resolve();
return;
}
var func = funcs[funcs.length - left]; // current func
var prom = func(lastResult).promise(); // for promise will return itself,
// for jquery ojbect will return promise.
// these handlers will be launched in order we specify them
prom.always(function() {
left--;
}).done(function(ret) {
defer.notify({
idx: funcs.length-left,
left: left,
result: ret,
success: true,
});
}).fail(function(ret) {
defer.notify({
idx: funcs.length-left,
left: left,
result: ret,
success: false,
});
}).always(function(ret) {
next(ret);
});
}
next();
return defer.promise();
};
상황에 따라 어떻게 사용합니까? 아름답 지 않을 수도 있지만 작동합니다.
function first() {
return ajax(...);
}
var id;
funciton second() {
return ajax(id, ...);
}
function third() {
return ajax(id, ...);
}
$.chain(first, second, third).progress(function(p) {
if(p.func == first)
id = p.result.identifier;
}).then(function() {
alert('everything is done');
});
또는 first함수 에서 해당 id 변수를 할당 할 수 있습니다 .
또는 이전 함수의 결과 만 필요한 경우 다음 방법을 사용할 수 있습니다.
function first() {
return ajax(...);
}
function second(first_ret) {
return ajax(first_ret.id, ...);
}
function third(second_ret) {
return ajax(second_ret.something, ...);
}
다음은 작동하는 것으로 보이며 동적 기능 목록을 허용합니다.
<html>
<head>
<title>demo chained synchronous calls</title>
</head>
<body>
<script src="http://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
function one(parms) {
console.log('func one ' + parms);
return 1;
}
function two(parms) {
console.log('func two ' + parms);
return 2;
}
function three(parms) {
console.log('func three ' + parms);
return 3;
}
function four(parms) {
console.log('func four ' + parms);
return 4;
}
var funcs = ['one', 'two', 'three', 'four'];
var rvals = [0];
function call_next_func() {
if (funcs.length == 0) {
console.log('done');
} else {
var funcname = funcs.shift();
console.log(funcname);
rvals.push(window[funcname](rvals));
call_next_func();
}
}
$(document).ready(function($){
call_next_func();
});
</script>
</body>
</html>
이를 수행하는 가장 좋은 방법은이를 위해 재사용 가능한 기능을 만드는 것입니다. 다음을 사용하여 한 줄의 코드로도 수행 할 수 있습니다 reduce.
function chainPromises(list) {
return list.reduce((chain, func) => chain ? chain.then(func) : func(), null);
}
This function accepts an array of callbacks which return a promise object, like your three functions.
Example usage:
chainPromises([first, second, third]).then(function (result) {
console.log('All done! ', result);
});
This way the result of first will also automatically be the parameter of second, so basically what happens is this:
first().then(function(res1) { return second(res1) })
.then(function(res2) { return third(res2) })
.then(function(result) { console.log('All done! ', result) });
And of course you could add as many functions to the array as you want.
To chain jquery ajax calls i did :
function A(){
return $.ajax({
url: url,
type: type,
data: data,
datatype: datatype,
success: function(data)
{
code here
}
});
}
function B(){
return $.ajax({
url: url,
type: type,
data: data,
datatype: datatype,
success: function(data)
{
code here
}
});
}
function C(){
return $.ajax({
url: url,
type: type,
data: data,
datatype: datatype,
success: function(data)
{
code here
}
});
}
A().done(function(data){
B().done(function(data){
C();
})
});
I just had the same problem, chaining ajax calls. After a few days of trying I finally did $.ajax({ async: false,... what completely did what I wanted to archieve. I just not did think of that. It might help others...
'Program Club' 카테고리의 다른 글
| WinRT의 UI 스레드에서 코드 실행 (0) | 2020.11.16 |
|---|---|
| Python은 키 목록이 사전에 있는지 확인합니다. (0) | 2020.11.16 |
| 매우 긴 문자열 목록에 대한 적절한 검색 / 검색 방법은 무엇입니까? (0) | 2020.11.16 |
| 데이터베이스가없는 Rails 모델 (0) | 2020.11.16 |
| C ++ 게터 / 세터 코딩 스타일 (0) | 2020.11.16 |