2014-07-13 4 views
0

JavaScript로 약속을 지키려고합니다. 약속이 무엇인지 아는 것처럼 느껴집니다. 그러나, 나는 그들을 사용하는 방법을 이해하지 않습니다. 학습을 위해 Node.js에서 데이터베이스를 쿼리하기로 결정했습니다. 내 코드에는 test.js.라는 JavaScript 파일 하나가 있습니다. Test.js은 다음과 같습니다JavaScript 약속 설정

Test.js

'use strict'; 

module.exports = function (app) { 
    var customerService = require('customer.js')(app); 

    var getCustomerTest = function() { 
    customerService.getCustomer(1).then(
     function (customer) { console.log(customer); }, 
     function (error) { console.log(error); } 
    ); 
    }; 
}; 

Customer.js

'use strict'; 

module.exports = function(app) { 
    var _ = require('lodash'); 
    var db = require('db'); 

    return { 
    getCustomer: function(customerID) { 
     try { 
     console.log('querying the database...'); 
     var database = db.connect(CONNECTION_STRING); 
     database.query('select * from customers where [ID]="' + customerID + '", function(error, result, response) { 
      if (error) { 
      // trigger promise error 
      } else { 
      // This throws an exception because displayMessage can't be found. 
      this.displayMessage('Success'); 

      // trigger promise success 
      } 
     }); 
     } catch (ex) { 
     // trigger promise error 
     } 
    }, 

    displayMessage: function(message) { 
     console.log(new Date() + ' - ' + message); 
    } 
    }; 
}; 

내가 설정에 getCustomer의 약속을하려고 사투를 벌인거야. 특히 데이터베이스 호출에 대한 호출이 비동기 적으로 발생하기 때문에 특히 그렇습니다. customerService.getCustomer에 대한 제 호출이 올바른 접근이라고 생각합니다. 그러나 getCustomer 내부에는 두 가지 문제가 있습니다.

  1. 약속을 어떻게 설정합니까?
  2. 데이터베이스 쿼리가 완료된 후 왜 displayMessage를 호출 할 수 없습니까? 어떻게해야합니까?

자바 스크립트 위즈!

+0

봐 - https://github.com/kriskowal/q 또한, "비동기"이없는 약속뿐만 asyncronous 콜백 - HTTPS : //github.com/caolan/async. 그들은 모두 좋은 문서를 가지고 있으며이 문제를 해결하기 위해 필요한 것입니다. – Dylan

답변

0

thisgetCustomerdisplayMessage가 들어있는 개체를 참조하지 않기 때문에

당신은 오류가있다 "나는 displayMessage를 호출 할 수 없습니다 이유는 데이터베이스 쿼리를 수행 한 후". 이것은 콜백 함수에 있고 컨텍스트가 변경 되었기 때문입니다.

당신은 displayMessage

getCustomer: function(customerID) { 
    //saving the context 
    var that = this; 
    try { 
    ... 
    database.query('select * from customers where [ID]="' + customerID + '", function(error, result, response) { 
     ... 
     // Now use it here to call displayMessage 
     that.displayMessage('Success'); 
     ... 
     } 
    }); 
    } catch (ex) { 
    ... 
    } 
}, 

가 액세스 할 수있는 올바른 컨텍스트에 대한 참조를 저장하고 그것을 사용할 필요 "어떻게 설정/내 약속을 반환합니까?"

귀하가 직접 계획하지 않는 한 약속 라이브러리가 필요합니다. 이를 위해 사용법을 보여 드리겠습니다. q library

두 가지 방법이 있지만 지연 사용을 보여 드리겠습니다.

기본 프로세스는 : ​​

  1. 는 비동기 함수/메소드를 호출하는 기능에 지연된 객체를 생성.
  2. promise 객체를 반환하십시오.
  3. promise 객체에 대해 then/fail/fin 등에 대한 적절한 콜백을 설정하십시오.
  4. async 함수의 콜백에서 지연을 해결하거나 거부하고 콜백에 필요한 인수를 전달합니다.
  5. 2 단계에서 설정 한 적절한 콜백이 순서대로 호출됩니다.

코드

var Q = require("q"); 
... 
getCustomer:{ 
    var deferred = Q.defer(), 
     database = db.connect(CONNECTION_STRING); 
    database.query("some query", function(error, result, response) { 
     if(error){ 
      //Anything passed will be passed to any fail callbacks 
      deferred.reject(error); 
     } else { 
      //Anything passed will be passed to any success callbacks 
      deferred.resolve(response); 
     } 
    }); 
    //Return the promise 
    return deferred.promise; 
} 
... 

customerService.getCustomer(1).then(function (customer) { 
    console.log(customer); 
}).fail(function (error) { 
    console.log(error); 
}).done(); 

는 Q 라이브러리는 꽤 많은 도움이 API의 기능이 있습니다. 노드 비동기 함수를 사용하여 약속을 얻는 데 도움이되는 몇 가지 방법. 읽어보기의 Adapting Node 섹션을 읽고 어떻게 완료되었는지 확인하십시오. Q의 브라우저 사용 시연

JSFiddle Demo

2 개 모듈 "Q"에서