지연된 콜백이란 무엇입니까?


15

함수를 다른 함수에 전달하고 그 함수가 제공된 함수를 마음대로 사용하는 콜백 아이디어를 이해합니다.

인터넷 검색 후 지연된 콜백을 이해하는 데 어려움을 겪고 있습니다.

누군가 간단한 설명을 해 주시겠습니까? 나는 루비로 프로그래밍하지만 C / C ++도 조금 알고 있지만, 무엇보다도 숙련 된 어셈블리 언어 프로그래머였습니다. 그래서 콜백 주소 스택과 비슷한 것이 궁금합니다. jquery 또는 node.js를 배우기를 바랍니다.이 지연된 콜백은 둘 다에 필수적인 것으로 보입니다. 나는 기본 스레딩 원리를 이해합니다 (mutex 객체가 머리를 아프게합니다).


jQuery의 Deferred객체 를 의미 합니까? 이것이 Node.js에 특정한 것입니까?
bfavaretto

1
아니요, 일반적으로 의미합니다. jquery와 가능한 node.js를 배우고 싶지만 지연 된 콜백이 실제로 무엇인지에 대한 핸들을 얻어야한다고 생각했습니다. 콜백에 대한 Wikipedia 기사를 읽었지만 지연 콜백에 대한 이해를 얻지 못했습니다.이 콜백을 사용하는 이러한 언어와 관련이있는 비동기 작업의 패러다임에 본질적으로 보입니다.


1
구현에 반대되는 지연된 콜백에 대한 개념적인 아이디어를 요구하고 있습니다. 더 명확하지 않으면 죄송합니다. 나는 사람들이 답을 얻는 방법을 알 수 있도록 설명하려고하는 아이디어와 프로그래밍 배경을 설명하기 위해 언어 예제를 더주었습니다. 지금까지 답변에 대해 대단히 감사합니다-나는 거기에 도착하고 있습니다!

좋아, 나는 당신에게 감사합니다. 그래도 대답을하는 방법을 모르겠습니다. 카메론 (Cameron)은 가장 간단하게 개념을 설명했고 그것이 제가 실제로 추구했던 것이었지만 다른 사람들도 차임하여 내 지식에 추가했습니다. 나는 이것에
익숙

답변:


4

요청에 따라 답변으로 제시된 의견은 다음과 같습니다.


JS의 함수가 일류 객체이므로 생성 된 시간이 지날 때까지 필요할 때까지 저장할 수 있다는 사실을 완전히 확신하지 못했습니다.

예를 들어, 파일에 쓰고 로그 메시지를 인쇄한다고 가정하십시오. "write ()"함수 (또는 무엇이든)를 호출하고 로그 메시지를 출력하는 함수를 전달합니다 (이것은 지연된 콜백 함수입니다). "write ()"는 주어진 함수에 대한 참조를 내부적으로 저장하고 파일에 쓰기를 시작하며 쓰기가 완료된 시점을 알기 위해 자체 콜백을 설정합니다. 그런 다음 쓰기가 완료되기 전에 반환됩니다. 내부 콜백은 어떻게 든 호출됩니다 (이것은 기본 프레임 워크의 작업입니다-node.js의 경우 이벤트 루프로 수행됩니다). 그런 다음 콜백을 호출하여 로그 메시지를 인쇄합니다.

"지연된"부분은 단순히 콜백 함수가 즉시 호출되지 않음을 의미합니다. 호출 은 적절한 시간까지 연기 됩니다. node.js의 많은 함수와 같은 비동기 함수의 경우, 주어진 콜백은 일반적으로 작업이 완료 될 때 (또는 오류가 발생할 때) 호출됩니다.

대부분의 내용은 node.js에서 비동기이지만 jQuery와 같은 브라우저에서는 대부분의 내용이 실제로 동 기적입니다 (AJAX 요청의 경우 제외). 일급 함수는 JavaScript에서 특히 편리하기 때문에 (특히 클로저 지원으로 인해) 콜백은 브라우저의 모든 곳에서 사용되지만 동기 작업에 대해 "지연"되지는 않습니다 (단, 즉시 호출되지 않는 한 제외) 당신은 나중에 호출하는 기능에 의해).

기본 시스템이 이벤트 중심이라는 사실은 지연된 콜백의 사용과 직교합니다. 모든 작업에 대해 스레드를 시작한 다음 스레드가 작업을 완료했을 때 이벤트를 전혀 사용하지 않고 주어진 콜백을 호출 한 (매우 느린) node.js 버전을 상상할 수 있습니다. 물론 이것은 끔찍한 모델이지만 내 요점을 보여줍니다 :-)


8

지연된 콜백의 작동 방식은 콜백을 추가 할 때마다 해당 콜백이 배열로 푸시됩니다. 그런 다음 지연된 객체 에서 .resolve()or .resolveWith()메소드를 호출 .done()하면 배열의 모든 콜백이 순서대로 실행됩니다.

이제 Deferred Object가 무엇인지 살펴볼 수 있습니다. 아래의 스 니펫을 예로 들어 보겠습니다.

var deferred = $.Deferred();
var promise = deferred.promise();

우리가 지금 가지고있는 것은 연기 된 대상과 약속 된 대상입니다. 지연된 객체 그러나 약속 오브젝트 만의 방법을 가지고, 모두에게 약속 객체와 동일한 방법을 가지고 .done(), .fail()그리고 .always()이는 각각의 지연에 대한 콜백 객체를 추가하기 위해 사용된다 event. 반면에 지연된 객체에는 몇 가지 다른 방법이 있습니다. 가장 중요한 것은 .resolve().reject()입니다. 이 메소드가 지연된 객체에서 호출되면 모든 콜백이 호출됩니다. .resolve()가 터 .done().always()그동안 콜백 .reject()메소드 호출 .fail().always()콜백.

일반적으로 지연된 오브젝트는 개인용 범위 내에 숨겨져 있으며, 약속 오브젝트는 함수에서 리턴되어 콜백을 배치 할 수 있습니다. 지연된 객체는 나중에 ajax 요청이 완료된 후 또는 이미지가로드 된 후, setTimeout 등으로 해결됩니다. 지연된 객체는 한 번만 해결 될 수 있음을 인식해야합니다. 이미 해결 된 경우 콜백이 즉시 호출됩니다.

다음은 내가 사용하는 또 다른 예입니다.

function loadImage(url) {
    var def = $.Deferred(),
        img = new Image();
    $(img).on("load error",function(e){
        if (e.type === "error") {
            def.reject(url);
        }
        else {
            def.resolve(url);
        }
    });
    img.src = url;
    // return the promise object so that callbacks can
    // be defined on the deferred object.
    return def.promise();
}
loadImage("foobar.jpg").done(function(){
    alert("The image is loaded!");
}).fail(function(){
    alert("The image failed to load!");
}).always(function(){
    alert("This is always called!");
});

jQuery의 $.Deferred()메소드 및 지연된 객체 에 대한 자세한 내용 은 http://api.jquery.com/category/deferred-object/를 방문하십시오.


지연된 콜백 개념을 머릿속으로 돌리면 이것은 아마도 귀중한 것입니다. 죄송하지만 지연된 콜백의 개념을 여전히 이해하지 못합니다. 나는 그 뒤에 개념적 아이디어를 찾고 있습니다. Mihia의 생각에 따라. 일단 내 머리를 잡을 수 있다면 js를 이해할 수 있습니다.

3

확실하지 않지만 지연 콜백은 비동기 콜백을 의미한다고 생각하므로 Google에 더 나은 행운을 빕니다.

내가 찾은 가장 좋은 설명은 http://www.nodebeginner.org입니다.

이봐, 아마도 ExpensiveFunction (), 당신의 일을하십시오. 그러나 단일 Node.js 스레드는 완료 될 때까지 여기에서 기다리지 않을 것입니다. 아래 코드 줄을 계속 실행할 것입니다. 이 callbackFunction () 여기 당신이 비싼 물건을 마쳤을 때 그것을 호출? 감사!"

이 예제에서 아마 ExpensiveFunction은 비 블로킹 (또는 비동기 함수)입니다. 즉, 즉시 실행되지 않고 소위 이벤트 루프에 배치됩니다. node.js 스레드는 실행을 계속하지만 특정 시점에서 이벤트 루프에서 무언가를 실행하기로 결정합니다. 아마 ExpensiveFunction에 도달하면이를 호출하고 아마 ExExsivesive 기능이 실행을 마치면 매개 변수로 전달 된 (지연된) 콜백을 호출합니다.

아마 ExpensiveFunction의 예로 fs.readFile 을 사용할 수 있습니다 .


감사. 그러나 이미 비싼 함수가 이미 반환되어 주요 실행 스레드로 돌아간 경우 어떻게 작동합니까? 나는 그 비트를 얻지 못합니다. 함수가 종료 된 후에도 어떤 방식으로 지속된다고 말하는가?

답을 수정했습니다. 지금은 더 명확합니다.

매우 도움이됩니다. 그러나 ...이 저장된 콜백 배열을 처리해야합니까? 내 말은,이 목록을 처리하는 것은 무엇입니까. 예를 들어 js 가이 콜백을 백그라운드에서 들어 올리거나 아무것도 수행하지 않아도되거나 이벤트로 인해 node.js 또는 특정 콜백을 호출하는 것이 있습니까? 죄송합니다, 당신이 말하고있는 것의 약 70 %가 받고 있지만 나머지는 약간 잃어 버렸습니다 :)

@tentimes- "이 목록을 처리하는 것은 무엇입니까"$ .Deferred () 객체가 목록을 처리하고 있습니다. 원래 지연된 객체 를 호출 .resolve()하거나 호출하면 .reject()콜백 목록이 호출됩니다.
user400654

2
@tentimes : JS의 함수가 일류 객체이므로 생성 된 시간이 지나서 필요할 때까지 저장할 수 있다는 사실을 완전히 확신하지 못했습니다. 예를 들어 파일에 쓰고 로그 메시지를 인쇄한다고 가정합니다. "write"함수 (또는 무엇이든)를 호출하고 로그 메시지를 출력하는 함수를 전달합니다. "write ()"는 주어진 함수에 대한 참조를 내부적으로 저장하고 파일에 쓰기를 시작하며 쓰기가 완료된 시점을 알기 위해 자체 콜백을 설정합니다. 그런 다음 쓰기가 완료되기 전에 반환됩니다. 있을 때 함수가 호출됩니다.
Cameron

3

JavaScript는 단일 스레드이므로이를 이해하기 위해 스레드 측면에서 생각할 수 없습니다. 다음은 jQuery를 사용하는 일반 및 비동기 콜백의 예입니다.

var regularCallback = function(evt) {
    alert("I'm a callback!")
}
var asyncCallback = function(data) {
    alert("I only run when an async operation finishes!")
}

// Bind the regular callback to a button's click event
$('#mybutton').on('click', regularCallback);

// Start an ajax request to the server. The request is asynchronous, so code
// below this line will execute immediately. The callback function
// will only be called when the request is complete.
$.get("http://google.com", asyncCallback);

이제 이것은 어딘가에 있습니다. 감사합니다. 따라서 비동기는 내가 아약스로 설정 한 이벤트에 대한 응답입니다. 단지 팜을 만들고 이벤트가 발생하면 콜백이 호출됩니까? 나는 그것을 얻는 것 같아요. node.js / jquery가 jquery usnig 지연된 객체객체 와 상호 작용하는 복잡한 시스템과 실제로 비슷한 방법을 사용하여 실제로 동일한 방법을 사용하지만 메소드를 사용합니까?

1
@tentimes, 정확히! 콜백은 일반적으로 이벤트에 대한 응답으로 실행됩니다 (그러나 "콜백"은 js 언어 구문이 아니기 때문에 때로는 다른 컨텍스트에서 사용됩니다). Kevin의 답변에서 보는 유예 대상 (약속)은 기본적으로 구문 설탕입니다. 일부 (비동기식) 이벤트가 트리거되면 "해결됨"또는 "거부 됨"을 받고 적절한 콜백을 호출합니다 ( "완료"또는 "실패", "항상"). jQuery에서 그것들을 사용하면 코드를 더 읽기 쉽게 만들 수 있으며, 예를 들어 아약스 요청을 실행 한 후 두 번째 콜백을 쉽게 추가하는 것과 같은 몇 가지 추가 트릭이 가능합니다.
bfavaretto

둘 다 비동기 콜백입니다
Raynos

1

지연된 콜백 (일명 Promices )을 사용하면 통증과 콜백 스파게티없이 순차적 인 비동기 코드를 작성할 수 있습니다.

$.when( doAjax(), doAnotherAjax() ).then( haveFunWithMoreAjax ).then( animateStuff );

'언제'는 함수가 병렬로 리턴 될 때까지 기다릴 then수 있으며 순차적으로 연결될 수 있습니다.

참고 사항 : jQuery deferreds ! = Promices / A , 구문은 약간 다릅니다.

주제에 대한 좋은 기사가 있습니다. 하나 는 IEBlog에 있고 다른 하나 임의의 블로그 에 있습니다. 인기있는 stackoverflow 질문


1
음 .. OP가 약간 다른 것을 물었 습니다. 글쎄,이 답변이 언젠가 다른 누군가를 도울 수 있기를 바랍니다.
c69
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.