programing

jQuery 연기 및 약속 - .then() vs.done()

bestprogram 2023. 6. 1. 23:03

jQuery 연기 및 약속 - .then() vs.done()

에 대해 'jQuery delays'와 ' delays'를 사용하는 것의 않습니다.then()&.done()성공적인 콜백을 위해.에릭 힌즈가 언급한 것은 알고 있습니다..done()그리고..success()동일한 기능에 매핑되지만 아마 그럴 것입니다..then()모든 콜백이 성공적인 작업이 완료되면 호출되기 때문입니다.

올바른 사용법을 가르쳐 주실 수 있는 분 있나요?

에 .done()지연이 해결되면 실행됩니다.에 .fail()지연이 거부되면 실행됩니다.

1 버전, jQuery 1.8 이전 then()그냥 통사적인 설탕이었어요

promise.then( doneCallback, failCallback )
// was equivalent to
promise.done( doneCallback ).fail( failCallback )

1.8 기준으로,then()는 의 별칭입니다.pipe()그리고 새로운 약속을 반환합니다. 자세한 내용은 여기를 참조하십시오.pipe().

success()그리고.error()는 할 수 있습니다.jqXHR호에의반개체로 된 개체ajax()이들은 다음에 대한 단순한 별칭입니다.done()그리고.fail()각각:

jqXHR.done === jqXHR.success
jqXHR.fail === jqXHR.error

또한.done()).: 1.8는 1.1에서수정어하만있지되터링야버가비 1.8에그 1.8.1는있문이열functions자는전을콜백고않한으백되지버만있▁(지▁is-▁filter▁non가functions▁out그backthough▁will버단 ▁1하(다어문있야는수▁call되▁with▁there▁in는정자열이니:합콜▁single일백터

// this will add fn1 to 7 to the deferred's internal callback list
// (true, 56 and "omg" will be ignored)
promise.done( fn1, fn2, true, [ fn3, [ fn4, 56, fn5 ], "omg", fn6 ], fn7 );

그것도 마찬가지입니다.fail().

반환 결과가 처리되는 방식에도 차이가 있습니다(체인이라고 함).done의 경우는 속박되지 않습니다.then체인 )

promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);
    return 123;
}).then(function (x){
    console.log(x);
}).then(function (x){
    console.log(x)
})

다음 결과가 기록됩니다.

abc
123
undefined

하는 동안에

promise.done(function (x) { // Suppose promise returns "abc"
    console.log(x);
    return 123;
}).done(function (x){
    console.log(x);
}).done(function (x){
    console.log(x)
})

다음을 얻을 수 있습니다.

abc
abc
abc

업데이트:

Btw. 언급하는 것을 잊었습니다. 원자 유형 값 대신 약속을 반환하면 외부 약속은 내부 약속이 해결될 때까지 대기합니다.

promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);
    return $http.get('/some/data').then(function (result) {
        console.log(result); // suppose result === "xyz"
        return result;
    });
}).then(function (result){
    console.log(result); // result === xyz
}).then(function (und){
    console.log(und) // und === undefined, because of absence of return statement in above then
})

이러한 방식으로 다음과 같은 병렬 또는 순차적 비동기 작업을 구성하는 것이 매우 간단합니다.

// Parallel http requests
promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);

    var promise1 = $http.get('/some/data?value=xyz').then(function (result) {
        console.log(result); // suppose result === "xyz"
        return result;
    });

    var promise2 = $http.get('/some/data?value=uvm').then(function (result) {
        console.log(result); // suppose result === "uvm"
        return result;
    });

    return promise1.then(function (result1) {
        return promise2.then(function (result2) {
           return { result1: result1, result2: result2; }
        });
    });
}).then(function (result){
    console.log(result); // result === { result1: 'xyz', result2: 'uvm' }
}).then(function (und){
    console.log(und) // und === undefined, because of absence of return statement in above then
})

위의 코드는 두 개의 http 요청을 병렬로 발행하여 요청을 더 빨리 완료하는 반면, 그 아래의 http 요청은 순차적으로 실행되어 서버 부하를 줄입니다.

// Sequential http requests
promise.then(function (x) { // Suppose promise returns "abc"
    console.log(x);

    return $http.get('/some/data?value=xyz').then(function (result1) {
        console.log(result1); // suppose result1 === "xyz"
        return $http.get('/some/data?value=uvm').then(function (result2) {
            console.log(result2); // suppose result2 === "uvm"
            return { result1: result1, result2: result2; };
        });
    });
}).then(function (result){
    console.log(result); // result === { result1: 'xyz', result2: 'uvm' }
}).then(function (und){
    console.log(und) // und === undefined, because of absence of return statement in above then
})

.done()의 콜백만 입니다.

.then() 콜백이 .

.fail()의 실패 . 즉, "Callback"이 있습니다.

그래서 당신이 무엇을 해야 하는지는 당신에게 달려 있습니다...당신은 그것이 성공하든 실패하든 상관이 있습니까?

연기 완료

지연이 해결된 경우에만 호출할 핸들러를 추가합니다.호출할 콜백을 여러 개 추가할 수 있습니다.

var url = 'http://jsonplaceholder.typicode.com/posts/1';
$.ajax(url).done(doneCallback);

function doneCallback(result) {
    console.log('Result 1 ' + result);
}

위에 글도 이렇게 쓸 수 있고,

function ajaxCall() {
    var url = 'http://jsonplaceholder.typicode.com/posts/1';
    return $.ajax(url);
}

$.when(ajaxCall()).then(doneCallback, failCallback);

연기된 후에

지연이 해결되거나 거부되거나 아직 진행 중인 경우 호출할 핸들러를 추가합니다.

var url = 'http://jsonplaceholder.typicode.com/posts/1';
$.ajax(url).then(doneCallback, failCallback);

function doneCallback(result) {
    console.log('Result ' + result);
}

function failCallback(result) {
    console.log('Result ' + result);
}

jQuery의 지연이 약속의 구현을 의미한다는 점에서 실제로 상당히 중요한 차이가 있습니다(그리고 jQuery 3.0은 실제로 이를 사양으로 구현하려고 합니다).

완료/완료 사이의 주요 차이점은

  • .done()사용자가 무엇을 하거나 무엇을 반환하는지에 관계없이 항상 시작한 약속/랩된 값을 반환합니다.
  • .then()항상 새 약속을 반환하며, 사용자는 전달한 함수가 반환한 것을 기준으로 해당 약속이 무엇인지 제어하는 역할을 담당합니다.

jQuery에서 네이티브 ES2015 Promise로 번역,.done()Promise 체인의 함수 주위에 "탭" 구조를 구현하는 것과 같습니다. 체인이 "해결" 상태에 있으면 함수에 값을 전달합니다.하지만 그 기능의 결과는 체인 자체에 영향을 미치지 않습니다.

const doneWrap = fn => x => { fn(x); return x };

Promise.resolve(5)
       .then(doneWrap( x => x + 1))
       .then(doneWrap(console.log.bind(console)));

$.Deferred().resolve(5)
            .done(x => x + 1)
            .done(console.log.bind(console));

둘 다 6개가 아니라 5개를 기록할 것입니다.

.then이 아닌 done과 doneWrap을 사용하여 로깅을 수행했습니다.이는 console.log 함수가 실제로 아무것도 반환하지 않기 때문입니다.그리고 만약 당신이 통과한다면, 어떤 것도 반환하지 않는 함수는 어떻게 될까요?

Promise.resolve(5)
       .then(doneWrap( x => x + 1))
       .then(console.log.bind(console))
       .then(console.log.bind(console));

로그에 기록:

5

미정의

무슨 일입니까?아무 것도 반환하지 않는 함수를 사용하여 전달했을 때 암묵적인 결과는 "정의되지 않음"이었습니다.물론 그 다음 방법으로 Promise[undefined]를 반환했고, 정의되지 않은 것으로 기록되었습니다.그래서 우리가 시작한 원래의 가치는 기본적으로 상실되었습니다.

.then()는 본질적으로 함수 구성의 한 형태입니다. 각 단계의 결과는 다음 단계의 함수에 대한 인수로 사용됩니다.그렇기 때문에 .done은 "탭"-> 실제로 구성의 일부가 아니라 특정 단계에서 값을 몰래 보고 그 값으로 함수를 실행할 뿐 실제로 구성을 변경하지는 않습니다.

이는 상당히 근본적인 차이이며, 네이티브 Promise가 .done 방식을 자체적으로 구현하지 않는 데는 상당한 이유가 있을 것입니다..fail 방법이 없는 이유는 더 복잡하기 때문입니다(즉, .fail/.catch는 .done/의 미러가 아닙니다).그러면 -> 맨 값을 반환하는 .vmdk의 함수는 전달된 값처럼 "계속" 거부되지 않습니다. 그러면 해결됩니다!)

then()항상 어떤 경우에도 호출된다는 것을 의미합니다.그러나 전달되는 매개 변수는 jQuery 버전마다 다릅니다.

1 버전, jQuery 1.8 이전 then()done().fail()그리고 모든 콜백 함수는 동일한 매개 변수를 공유합니다.

1, 하만jQuery 1.8부then()새 약속을 반환하며, 반환된 값이 있으면 다음 콜백 함수로 전달됩니다.

다음 예를 보겠습니다.

var defer = jQuery.Deferred();

defer.done(function(a, b){
            return a + b;
}).done(function( result ) {
            console.log("result = " + result);
}).then(function( a, b ) {
            return a + b;
}).done(function( result ) {
            console.log("result = " + result);
}).then(function( a, b ) {
            return a + b;
}).done(function( result ) {
            console.log("result = " + result);
});

defer.resolve( 3, 4 );

jQuery 1.8 이전 버전에서는 다음과 같이 답해야 합니다.

result = 3
result = 3
result = 3

든모.result3이 걸립니다.그리고.then()함수는 항상 동일한 지연 개체를 다음 함수로 전달합니다.

그러나 jQuery 1.8 기준 결과는 다음과 같습니다.

result = 3
result = 7
result = NaN

첫 번째 왜하면첫는째번냐▁the.then()는 새 값 7한 매개 변수)은 다음 함새약반그고값이 7(리이다전유 7)로됩니다.done() 두 그서두번째래번.done()글을 쓰다result = 7 번째 두번째째.then()을 값을로 으로 사용합니다.a그리고 테이크undefinedb 두 그서두번째래번.then()는 매개 NaN과 "NaN"을 새 합니다.done()결과로 NaN을 인쇄합니다.

만 합니다..then()

.done()에는 이점이 없으며 다음과 같은 단점이 있습니다.

  • 체인을 올바르게 연결할 수 없습니다.
    • a.done().done()는 와동합다니와 .a.done(); a.done()은 로추정 수있는으로 추정할 수 .a.then(); a.then()
    • a.then().then()에서는 사용할 수 없습니다..done()
  • 록들블resolve()콜 (모두).done()핸들러가 동기적으로 실행됨)
  • resolve()된 에서 예외가 발생할 수 ..done()
  • .done()지연된 부분의 반값:
    • .done().
  • .then()에는 이러한 .

나는 일시적으로 생각했습니다..then(oneArgOnly) 상항필함을 요구합니다..catch()되지 않도록 : " 그서어예조도않무만지지시되다아니, "닙은더이사이", "실상그것떤외히용래":unhandledrejection 로그 되지 않음.then()콘솔의 예외(기본값).아주 합리적입니다!사용할 이유가 없습니다..done()조금도.

증명

다음 코드 조각은 다음을 나타냅니다.

  • 든모의.done()는 핸러는다지동호출로됩다니으기의 됩니다.resolve()
    • 1, 3, 5, 7로 기록됨
    • 스크립트가 아래로 떨어지기 전에 기록됩니다.
  • 예의외의 ..done()resolve()방문자
    • 주위의 캐치볼을 통해 기록된.resolve()
  • 을 더 깨뜨리지 ..done()결의안
    • 8과 10은 기록되지 않습니다!
  • .then()이러한 문제가 없습니다.
    • 스레드가 유휴 상태로 전환된 후 2, 4, 6, 9, 11로 기록됨
    • )unhandledrejection인 것 같습니다)

BTW의 , 예외:.done()제대로 잡을 수 없습니다. 동기화된 패턴 때문입니다..done()오류는 다음 지점에서 발생합니다..resolve()(가 될 수 (라이브러리 코드가 될 수 있습니다!)에서.done()지연이 이미 해결된 경우 범인을 연결하는 호출입니다.

console.log('Start of script.');
let deferred = $.Deferred();
// deferred.resolve('Redemption.');
deferred.fail(() => console.log('fail()'));
deferred.catch(()=> console.log('catch()'));
deferred.done(() => console.log('1-done()'));
deferred.then(() => console.log('2-then()'));
deferred.done(() => console.log('3-done()'));
deferred.then(() =>{console.log('4-then()-throw');
    throw 'thrown from 4-then()';});
deferred.done(() => console.log('5-done()'));
deferred.then(() => console.log('6-then()'));
deferred.done(() =>{console.log('7-done()-throw');
    throw 'thrown from 7-done()';});
deferred.done(() => console.log('8-done()'));
deferred.then(() => console.log('9-then()'));

console.log('Resolving.');
try {
    deferred.resolve('Solution.');
} catch(e) {
    console.log(`Caught exception from handler
        in resolve():`, e);
}
deferred.done(() => console.log('10-done()'));
deferred.then(() => console.log('11-then()'));
console.log('End of script.');
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh"
crossorigin="anonymous"
></script>

jQuery 3.0에서는 예상치 못한 동작으로 쉽게 이어질 수 있으며 이전 답변에서는 언급하지 않은 중요한 차이점이 하나 더 있습니다.

다음 코드를 고려합니다.

let d = $.Deferred();
d.done(() => console.log('then'));
d.resolve();
console.log('now');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>

출력:

then
now

이제 대체제를 바꿔보세요.done()타고then()동일한 스니펫에서:

var d = $.Deferred();
d.then(() => console.log('then'));
d.resolve();
console.log('now');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>

이제 출력:

now
then

따라서 즉시 해결된 지연에 대해 함수는 다음으로 전달되었습니다.done()는 항동기식으로반모에인전든수다달니됩는면상호는출되로 됩니다.then()비동기가 호출됩니다.

업그레이드 안내서에 언급된 것처럼 두 콜백이 동시에 호출되는 이전 jQuery 버전과는 다릅니다.

Promise/A+ 준수에 필요한 또 다른 동작 변경은 지연된 .then() 콜백이 항상 비동기식으로 호출된다는 것입니다.이전에는 .then() 콜백이 이미 해결되거나 거부된 지연된 콜백에 추가된 경우 콜백이 즉시 동기적으로 실행됩니다.

다른 답변에서 찾기 어려웠던 매우 간단한 정신적 매핑이 있습니다.

  • donetap파랑새의 약속처럼

  • thenthenES6 약속에서와 같이

위의 답변 외에도 다음과 같은 답변이 있습니다.

. 그렇다면 진정한 힘은 유창한 방식으로 Ajax 호출을 체인화하여 콜백 지옥을 피할 수 있는 가능성입니다.

예:

$.getJSON( 'dataservice/General', {action:'getSessionUser'} )
    .then( function( user ) {
        console.log( user );
        return $.getJSON( 'dataservice/Address', {action:'getFirstAddress'} );
    })
    .then( function( address ) {
        console.log( address );
    })

여기 두 번째. 그리고 반환된 $.getJ를 따릅니다.아들.

.done()약속 체인을 종료하여 다른 어떤 단계도 추가할 수 없도록 합니다.도 이은것 jQuery 약리않지되예은발수의있다미니를 사용하여 할 수 예외를 수 합니다. 왜냐하면 누구도 다음을 사용하여 처리할 수 없기 때문입니다..fail().

면에서,에 더 , 은 실적인측서, 당이약더단붙계합없, 당신다사야다니해를 사용해야 합니다..done()자세한 내용은 약속을 이행해야 하는 이유를 확인하십시오.

언급URL : https://stackoverflow.com/questions/5436327/jquery-deferreds-and-promises-then-vs-done