2013-02-10 2 views
0

저는 아직 비동기 프로그래밍에 익숙하지 않은데, 제가하려고하는 것을 성취 할 수있는 더 좋은 방법이 있는지 궁금해하고 있습니다.함수에서 다중 콜백의 결과를 사용하는 좀 더 우아한 방법?

exports.content = function(req, res){ 
    OPID = req.params.id; 

    titles.findOne({postID: OPID}, function (err, post) { //function #1 
    if (err) throw(err); 

    readComment(OPID, function(comment){ //function #2 

     branchFilter.getBranches(function(branches){ //function #3 

     res.render('content', {title: post.title, content: post.body, OPID: post.postID, comments: comment, branches: branches}); 
     }) 
    }); 
    }); 
}; 

이 예제에서는 콜백을 사용하여 다른 모듈에서 데이터를 검색하는 세 개의 중첩 함수가 있습니다. res.render 문에이 모든 데이터가 있어야합니다. 이 접근 방식을 계속 사용한다면 더 많은 중첩 된 함수가 필요하다고 생각합니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

+2

[약속] (https://github.com/kriskowal/q). –

+2

https://github.com/caolan/async – JohnnyHK

답변

1

JohnnyHK가 제안 했으므로 좋은 비동기 라이브러리가 도움이 될 것입니다. 나는 또한 Caolan's async을 제안 할 것이다. 런타임이 문제라면 async이 최선의 선택이 아닐지라도 autoforEach의 조합으로 거의 모든 비동기 문제를 해결할 수 있습니다. 다음과 같이 내가 코드를 다시 작성할 것 : auto이하는 무엇

exports.content = function(req, res){ 
    OPID = req.params.id; 

    async.auto({ 
    post: function(next) { 
     titles.findOne({postID: OPID}, next); 
    }, 
    comment: function(next) { 
     readComment(OPID, function(comment){ next(null, comment); }); 
    }, 
    branches: function(next) { 
     branchFilter.getBranches(function(branches){ next(null, branches); }); 
    } 
    }, function(err, results) { 
    if(err) throw(err); 
    res.render('content', {title: results.post.title, content: results.post.body, OPID: results.post.postID, comments: results.comment, branches: results.branches}); 
    }); 
}; 

을 함수의 사전을한다 (사전에 다른 기능에 대한 옵션 종속성 - 이상 비동기 추가 정보를 참조)에 사전으로 결과를 전달합니다 두 번째 인수, "최종"함수. 기능의 임의의 콜백을 비 - 널 err (첫번째 인수)를 통과하면

는, 다른 함수를 호출하고 즉시 "최종"함수 errnull 결과를 전달하지 않습니다.

branchescomment 함수에서 익명 함수를 전달해야하는 방법에 유의하십시오. 이 async 라이브러리의 다른 함수와 마찬가지로 auto은 콜백의 첫 번째 인수가 오류 값이고 두 번째 인수가 결과가 될 것으로 예상하기 때문입니다.

당신 예를 들어
2

, 그냥 콜백을 사용하여 깨끗한 코드를 작성하는 방법에 대한 아주 좋은 개요를 제공 http://callbackhell.com/를 살펴 보자 데이터


을 유도 할 수있는 기능을 가지고있다.

var form = document.querySelector('form') 
form.onsubmit = function(submitEvent) { 
    var name = document.querySelector('input').value 
    request({ 
    uri: "http://example.com/upload", 
    body: name, 
    method: "POST" 
    }, function(err, response, body) { 
    var statusMessage = document.querySelector('.status') 
    if (err) return statusMessage.value = err 
    statusMessage.value = body 
    }) 
} 

이 코드가 다음 해당 사이트에서 복사

이름 이메일 기능입니다

다음

은 서버에 AJAX 요청을하려면 브라우저 요청을 사용하여 일부 (지저분한) 브라우저의 자바 스크립트입니다 다음 두 가지 익명 함수. 엠마임을 알려주세요!

var form = document.querySelector('form') 
form.onsubmit = function formSubmit(submitEvent) { 
    var name = document.querySelector('input').value 
    request({ 
    uri: "http://example.com/upload", 
    body: name, 
    method: "POST" 
    }, function postResponse(err, response, body) { 
    var statusMessage = document.querySelector('.status') 
    if (err) return statusMessage.value = err 
    statusMessage.value = body 
    }) 
} 

당신이 볼 수 있듯이 기능을 명명하는 것은 매우 간단하고 코드에 어떤 좋은 일을한다 :

  • 쉽게 코드
  • 예외가 일어날 때 실제 함수를 참조 스택 추적을 얻을 것이다 읽을 수 있습니다
  • 은 코드를 얕게 유지하거나 깊게 중첩하지 않아도되므로 다음 지점으로 이동하게합니다.
0 이 덜 무서운처럼

function formSubmit(submitEvent) { 
    var name = document.querySelector('input').value 
    request({ 
    uri: "http://example.com/upload", 
    body: name, 
    method: "POST" 
    }, postResponse) 
} 

function postResponse(err, response, body) { 
    var statusMessage = document.querySelector('.status') 
    if (err) return statusMessage.value = err 
    statusMessage.value = body 
} 

document.querySelector('form').onsubmit = formSubmit 

코드 :

마지막 예제에서 코드 얕은

건물을 유지의 조금 더 나아가 코드에서 벌어지고있는 트리플 수준의 중첩을 제거하자 보고 수정하기 쉽고, 나중에 리팩토링하고 해킹 할 수 있습니다.

모듈화!

이것은 가장 중요한 부분입니다. 누구나 모듈 (일명 라이브러리)을 만들 수 있습니다. Isaac Schlueter (node.js 프로젝트)의 인용문은 다음과 같습니다. "각각 하나씩하는 작은 모듈을 작성하고 큰 모듈을 다른 모듈로 조합하십시오. 콜백 지옥에 갈 수는 없습니다. . "

위에서 언급 한 상용구 코드를 꺼내서 두 개의 파일로 나누어서 모듈로 만들어 보겠습니다. 브라우저와 서버 모두에서 JavaScript를 작성하기 때문에 두 가지 모두에서 작동하는 메서드를 보여줄 것이지만 여전히 멋지고 간단합니다.

여기에서 우리의 두 가지 기능을 포함 formuploader.js라는 새로운 파일입니다 전에 :

function formSubmit(submitEvent) { 
    var name = document.querySelector('input').value 
    request({ 
    uri: "http://example.com/upload", 
    body: name, 
    method: "POST" 
    }, postResponse) 
} 

function postResponse(err, response, body) { 
    var statusMessage = document.querySelector('.status') 
    if (err) return statusMessage.value = err 
    statusMessage.value = body 
} 

exports.submit = formSubmit 
+0

우수 참조 http://callbackhell.com – abernier

관련 문제