2012-11-25 9 views
1

나는 내부에 단일 사용자를 붙잡을 수있는 사용자 컬렉션을 만들고 있습니다. 이것은 다른 시스템에서 일치하는 데 사용되므로 사용자를 한 번로드 한 다음 나중에 세부적으로 일치시킬 수 있어야합니다. 그러나 내부 메서드에서 외부 사용자 컬렉션에 액세스하는 데 문제가 있습니다.바깥 쪽 범위에 액세스하기

function Users(){ 

    var allUsers; 

    this.getUsers = function() { 
     // ajax to that Jasmine behaves  
     $.ajax({ 
      url: '../app/data/jira_users.json', 
      async: false, 
      dataType: 'json', 
      success: function(data) { 
       allUsers = data; 
      } 
     }); 
     return allUsers; 
    }; 

    this.SingleUser = function (name) { 
     var rate = 0.0; 
     var position; 

     this.getRate = function() { 
      if(position === undefined){ 
       console.log('>>info: getting user position to then find rate'); 
       this.getPosition(); 
      } 

      $.ajax({ 
       url: '../app/data/rates.json', 
       async: false, 
       dataType: 'json', 
       success: function(data) { 
        rate = data[position]; 
       } 
      }); 
      return rate; 
     }; 

     this.getPosition = function() { 
      console.log(allUsers); 
      //position = allUsers[name]; 
      return position; 
     }; 

     //set name prop for use later I guess. 
     this.name = name; 
    }; 
} 

이 모든 시작하고있다 테스트 :

it("get single user's position", function(){ 
    var users = new Users(); 
    var someone = new users.SingleUser('bgrimes'); 
    var position = someone.getPosition(); 
    expect(position).not.toBeUndefined(); 
    expect(position).toEqual('mgr'); 
}); 

하는 getPosition 방법은 (명백한 수 있습니다) 문제입니다 ALLUSERS 등은 항상 정의되지 않습니다. 제가 여기있는 것은 또 다른 시도입니다. 나는 몇 가지 방법을 시도했습니다. 나는 문제가 Users.getUsers가 시작하기 위해 호출되는 방법이라고 생각하지만, 바깥 쪽 및 바깥 쪽 변수를 올바르게 사용하고 있는지 확신 할 수 없습니다.

+1

환상적인 ** async ** 세계에 오신 것을 환영합니다! 너는 그렇게 할 수 없다. – SLaks

+0

그래,이 작업을 덜 비동기로 만들려고했다. 실패. 감사. – BryanGrimes

답변

1

:

this.getUsers = function (callback) { 
    // ajax to that Jasmine behaves  
    $.ajax({ 
     url: '../app/data/jira_users.json', 
     async: false, 
     dataType: 'json', 
     success: function(data) { 
      callback(data); 
     } 
    }); 
}; 

그리고 통화의 라인을 따라 다음과 같습니다

뭔가 같은 유스 케이스가 재스민 테스트 케이스 인 것을 본다. 따라서 테스트를 성공적으로 수행 할 수있는 방법이 있습니다. 그리고 다음과 같이하면 테스트를 수행하기 위해 실제로 어떤 종류의 서버를 실행할 필요가 없습니다.

var dataThatYouWouldExpectFromServer = { 
    bgrimes: { 
     username: 'bgrimes', 
     show: 'chuck', 
     position: 'mgr' 
    } 
}; 

it("get single user's position", function(){ 
    var users = new Users(); 
    spyOn($, 'ajax').andCallFake(function (ajaxOptions) { 
     ajaxOptions.success(dataThatYouWouldExpectFromServer); 
    }); 
    users.getUsers(); 
    var someone = new users.SingleUser('bgrimes'); 
    var position = someone.getPosition(); 
    expect(position).not.toBeUndefined(); 
    expect(position).toEqual('mgr'); 
}); 

이것은 당신이 그것은 또한 당신이 등 당신은 아무것도 'dataThatYouWouldExpectFromServer'을 설정할 수 있습니다 실패, 예기치 않은 데이터에 대한 테스트를 조롱 할 수있는 반환 할 것을 무엇이든 아약스 호출 수익을 만들 것입니다 언제든지 원하는 결과를 테스트 할 수 있지만 각 결과에 JSON 파일을 사용하지 않으려는 경우 도움이 될 수 있습니다.

Sorta-edit - 테스트 케이스는 수정되지만 코드는 수정되지 않습니다. 내 추천은 아약스 호출 반환에 의존 할 때마다 호출하는 메서드에 '콜백'인수가 있는지 확인해야한다는 것입니다. 예를 들면 다음과 같습니다.

중첩 할 수 있으며, 콜백을 생성 한 다음 서로의 인수로 사용할 수도 있습니다.

var users = new Users(), currentUser; 

var showUserRate = function() { 
    //show his rate 
    //this won't require a callback because we know it's loaded. 
    var rate = currentUser.getRate(); 
} 

var usersLoaded = function() { 
    //going to load up the user 'bgrimes' 
    currentUser = new users.SingleUser('bgrimes'); 
    currentUser.getRate(showUserRate); 
} 

users.getUsers(usersLoaded); 
+0

완벽하게 건배. Jasmine 테스트는 즉각적인 두통을 일으키고 있었지만, 나는 결코 그대로 ​​작동 할 것이라고 생각하지 않았습니다. 이렇게하면 문제, 코드 및 테스트를 모두 해결할 수 있습니다. – BryanGrimes

1

allUsers의 데이터를 채우기 위해 당신의 접근 방식은 결함이
JQuery와의 AJAX 호출이 너무 users.getAllUsers에 대한 모든 호출이 아무것도 반환됩니다 나중에 JQuery와 아약스의 성공 기능이 채워진 얻을 것이다 다음 allUsers를 호출 할 때 비동기입니다

1

this.getUsers()은 작동하지 않습니다. allUsers의 반환은 데이터를 가져 오는 ajax 요청과는 독립적입니다. 왜냐하면 ajax가 비동기이기 때문입니다. getRate()과 동일합니다.

콜백 참조를 사용하여 getUsers()을 호출해야하며, Ajax 요청이 완료되면 데이터를 콜백 함수에 전달합니다. , 다른 사람이 당신이 밖으로 입력 한대로 작동하지 않습니다이 올바른지하지만

var user_data = null; 
Users.getUsers(function(data) { 
    user_data = data; 
}); 
+0

감사합니다. 콜백은 현재 "go to"패턴에 있지 않으며 분명히 최대한 빨리해야합니다. – BryanGrimes

관련 문제