jQuery Deferred
에는 함수의 비동기 체인을 구현하는 데 사용할 수있는 두 가지 함수가 있습니다.
then()
deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred
doneCallbacks Deferred가 해결 될 때 호출되는 함수 또는 함수 배열입니다.
failCallbacks Deferred가 거부 될 때 호출되는 함수 또는 함수 배열입니다.
pipe()
deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise
doneFilter Deferred가 해결 될 때 호출되는 선택적 함수입니다.
failFilter Deferred가 거부 될 때 호출되는 선택적 함수입니다.
나는 then()
그보다 조금 더 오래되었다는 것을 알고 pipe()
있으므로 후자는 약간의 추가 이점을 추가해야하지만 그 차이가 정확히 무엇인지 알 수 없습니다. 둘 다 이름이 다르지만 거의 동일한 콜백 매개 변수를 사용하며 a를 반환하는 Deferred
것과 a 를 반환하는 것의 차이 Promise
는 약간 보입니다.
저는 공식 문서를 계속해서 읽었지만 항상 너무 “밀집되어”머리를 감쌀 수 없으며 검색을 통해 한 기능 또는 다른 기능에 대해 많은 토론을 찾았지만 실제로 다른 기능을 명확히하는 것을 찾지 못했습니다. 각각의 장단점.
그렇다면 언제 사용하는 then
것이 더 좋으며 언제 사용하는 것이 더 좋 pipe
습니까?
덧셈
Felix의 탁월한 답변 은이 두 기능이 어떻게 다른지 명확히하는 데 도움이되었습니다. 그러나 나는의 기능이 때 시간이 있는지 궁금 then()
의 그것 바람직하다 pipe()
.
전자가 후자가 할 수있는 모든 것을 할 수있는 것 pipe()
보다 더 강력한 것이 분명합니다 then()
. 사용하는 한 가지 이유 then()
는 이름이 동일한 데이터를 처리하는 기능 체인의 종료로서의 역할을 반영 하기 때문일 수 있습니다.
그러나 새로운 반환으로 인해 할 수없는 then()
원본 Deferred
을 반환 해야하는 사용 사례가 있습니까?pipe()
Promise
답변
이후 jQuery를 1.8 .then
로 동일하게 동작합니다 .pipe
:
지원 중단 알림 : jQuery 1.8부터이
deferred.pipe()
메서드는 더 이상 사용되지 않습니다.deferred.then()
를 대체하는 방법은 대신 사용해야합니다.
과
jQuery를 1.8으로 의
deferred.then()
방법은 지금은 사용되지 않는 대신, 상태 및 기능을 통해 지연된의 값을 필터링 할 수있는 새로운 약속을 반환하는deferred.pipe()
방법을.
아래의 예는 여전히 도움이 될 수 있습니다.
그들은 다른 목적으로 사용됩니다.
-
.then()
프로세스의 결과로 작업하고 싶을 때, 즉 문서에서 말하는 것처럼 지연된 객체가 해결되거나 거부 될 때 사용됩니다. 그것은 사용하는 것과 동일.done()
하거나.fail()
. -
어떻게 든 결과
.pipe()
를 (사전) 필터링 하는 데 사용 합니다 . 콜백의 반환 값은 및 콜백에.pipe()
인수로 전달됩니다 . 또한 다른 지연된 객체를 반환 할 수 있으며 다음 콜백이이 지연된 항목에 등록됩니다.done
fail
.then()
(또는.done()
,.fail()
) 의 경우 가 아니라 등록 된 콜백의 반환 값이 무시됩니다.
그래서 사용하는 것이 아닌 하나 .then()
또는 .pipe()
. 당신은 할 수 사용 .pipe()
과 같은 목적으로 .then()
하지만, 그 반대는 유지되지 않습니다.
예 1
일부 작업의 결과는 객체의 배열입니다.
[{value: 2}, {value: 4}, {value: 6}]
값의 최소값과 최대 값을 계산하려고합니다. 두 개의 done
콜백 을 사용한다고 가정 해 보겠습니다 .
deferred.then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var min = Math.min.apply(Math, values);
/* do something with "min" */
}).then(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
var max = Math.max.apply(Math, values);
/* do something with "max" */
});
두 경우 모두 목록을 반복하고 각 개체에서 값을 추출해야합니다.
두 콜백에서 개별적으로이 작업을 수행 할 필요가 없도록 미리 값을 추출하는 것이 더 낫지 않을까요? 예! 그리고 그것이 우리가 사용할 수있는 것 .pipe()
입니다 :
deferred.pipe(function(result) {
// result = [{value: 2}, {value: 4}, {value: 6}]
var values = [];
for(var i = 0, len = result.length; i < len; i++) {
values.push(result[i].value);
}
return values; // [2, 4, 6]
}).then(function(result) {
// result = [2, 4, 6]
var min = Math.min.apply(Math, result);
/* do something with "min" */
}).then(function(result) {
// result = [2, 4, 6]
var max = Math.max.apply(Math, result);
/* do something with "max" */
});
분명히 이것은 구성된 예이며이 문제를 해결하기위한 여러 가지 (아마도 더 나은) 방법이 있지만 요점을 설명하기를 바랍니다.
예 2
Ajax 호출을 고려하십시오. 때로는 이전 호출이 완료된 후 하나의 Ajax 호출을 시작하려고합니다. 한 가지 방법은 done
콜백 내에서 두 번째 호출을 만드는 것입니다 .
$.ajax(...).done(function() {
// executed after first Ajax
$.ajax(...).done(function() {
// executed after second call
});
});
이제 코드를 분리하고 다음 두 Ajax 호출을 함수 안에 넣길 원한다고 가정합니다.
function makeCalls() {
// here we return the return value of `$.ajax().done()`, which
// is the same deferred object as returned by `$.ajax()` alone
return $.ajax(...).done(function() {
// executed after first call
$.ajax(...).done(function() {
// executed after second call
});
});
}
두 번째 Ajax 호출에 makeCalls
대한 콜백을 첨부하기 위해 호출 하는 다른 코드를 허용하기 위해 지연된 객체를 사용하고 싶지만
makeCalls().done(function() {
// this is executed after the first Ajax call
});
두 번째 호출이 done
콜백 내부에서 이루어 지고 외부에서 액세스 할 수 없기 때문에 원하는 효과를 얻지 못할 것 입니다.
해결책은 .pipe()
대신 사용하는 것입니다.
function makeCalls() {
// here we return the return value of `$.ajax().pipe()`, which is
// a new deferred/promise object and connected to the one returned
// by the callback passed to `pipe`
return $.ajax(...).pipe(function() {
// executed after first call
return $.ajax(...).done(function() {
// executed after second call
});
});
}
makeCalls().done(function() {
// this is executed after the second Ajax call
});
를 사용 .pipe()
하면 호출의 실제 흐름 / 순서를 노출하지 않고도 “내부”Ajax 호출에 콜백을 추가 할 수 있습니다.
일반적으로 지연된 객체는 코드를 분리하는 흥미로운 방법을 제공합니다. 🙂
답변
을 반드시 사용해야 then()
하는 경우는 없습니다 pipe()
. pipe()
전달 될 값을 항상 무시하도록 선택할 수 있습니다 . 사용시 약간의 성능 저하 가 있을 수 pipe
있지만 문제가되지는 않습니다.
따라서 pipe()
두 경우 모두 단순히 항상 사용할 수있는 것처럼 보일 수 있습니다 . 그러나을 사용 pipe()
하면 코드를 읽는 다른 사람 (지금부터 6 개월 후 자신을 포함)에게 반환 값이 중요하다는 사실 을 알릴 수 있습니다. 폐기하는 경우이 의미 구조를 위반하는 것입니다.
사용되지 않는 값을 반환하는 함수가있는 것과 같습니다. 혼란 스럽습니다.
그러니 then()
필요할 때와해야 할 때 사용하십시오 pipe()
.
답변
실제로 .then()
와 사이의 차이는 .pipe()
불필요한 것으로 간주되었으며 jQuery 버전 1.8과 동일하게 만들어졌습니다.
에서 에 의해 코멘트jaubourg
jQuery의 버그 트래커에 티켓 # 11010 “MAKE DEFERRED.THEN == DEFERRED.PIPE LIKE 약속 / A”
1.8에서는 이전 버전을 제거하고 현재 파이프로 교체합니다. 그러나 매우 슬픈 결과는 사람들에게 비표준 done, fail 및 progress를 사용하도록 알려야한다는 것입니다. 제안이 단순하고 효율적이며 콜백을 추가한다는 의미를 제공하지 않기 때문입니다.
(엠파 시스 광산)