2013-05-14 5 views
0

내가 읽은 바로는 중첩 함수는 "정적 함수"또는 심지어 Singleton 구현을 사용하여 피할 수있는 추가 선언/파괴를 유발합니다. 또한 "new"는 함수 또는 객체의 두 인스턴스가 독립적 인 복사본 인 동일한 작업을 수행합니다.nodejs/javascript의 중첩 함수

사실인가요? 그렇다면 중첩 된 함수와 동일한 기능을 "new"로 사용하려면 어떻게해야합니까? 이것은 서버가 nodejs/javascript에있는 게임을위한 것입니다. 중첩 된 함수의 약 8 단계에 도달했으며 걱정하기 시작했습니다.

예 :

DB.cityUpdateUpkeep = function(cuid) 
{ 
/** @type {Array} */ 
var buildings = null; 

DB.cityGet(cuid, function(error, city) 
{ 
    if(error) 
    { 
     console.log("Couldn't get city"); 
    } 
    else 
    { 
     DB.iBuildings.find({cuid:cuid}, function(error, cursor) 
     { 
      if(error) 
      { 
       console.log("-error:"); 
       console.log(error); 
      } 
      else 
      { 
       cursor.toArray(function(error, response) 
       { 
        if(error) 
        { 
         console.log("-error:"); 
         console.log(error); 
        } 
        else 
        { 
         console.log("-the response:"); 
         console.log(response); 
         buildings = response; 

         var income = city.resources.income; 
         var storage = city.resources.storage; 
         var stored = city.resources.stored; 

         for(var buildingID in buildings) 
         { 
          var building = buildings[ buildingID ]; 
          var blueprint = DB.bBuildings[ building.buid ]; 

          if(blueprint.resources.income) 
          { 
           income = Utils.sumObjects(income, blueprint.resources.income); 
          } 

          if(blueprint.resources.storage) 
          { 
           storage = Utils.sumObjects(storage, blueprint.resources.storage); 
          } 

          if(blueprint.resources.stored) 
          { 
           stored = Utils.sumObjects(stored, blueprint.resources.stored); 
          } 
         } 

         console.log("cuid: " + city._id + " income: " + income + " storage " + storage + " stored " + stored); 
        } 
       }); 
      } 
     }); 
    } 
}); 
}; 
+3

어떻게 중첩합니까? 이 기능들은 무엇입니까? 8 레벨? 진지하게? 중첩 된 함수가 아닌 콜백과 같은 소리입니다. – Joseph

+0

예제를 제공해 주시겠습니까? 질문은 지금 너무 일반적이어서 문제를 실제로 돕지 않고 이름 지정 기능, 약속 사용, 이벤트 사용에 관한 기사로 안내하여 해결할 수 있습니다. –

+0

예제를 추가했습니다 – Discipol

답변

0

한 용액 대신 익명을 갖는 콜백 함수를 저장하는 것이다. 그것들을 재사용하는 것이 더 쉽습니다.

DB.cityUpdateUpkeep = function (cuid) { 
    var findHandler = function() { ... }; 

    DB.cityGet(cuid, function (error, city) { 
     ... 
     DB.iBuildings.find({cuid:cuid}, findHandler); 
     ... 
    }); 
}; 
+0

최상위 수준에서 최하위 수준까지 "도시"를 사용하는 방법에 유의하십시오. 나는이 모든 기능을 과도하게 복잡하게 할 수있는 매개 변수를 많이 필요로합니다. 그냥 내가 맨 아래에 필요한 매개 변수를 추가한다고 생각해보십시오. 나는 전체 사슬에서 그 가치를 전달해야 할 것입니다 : | 어쨌든 이러한 중첩 된 함수는 얼마나 나쁜 것입니까? – Discipol

0

내가 대신 콜백의 무리를 가지고 당신이 (비동기 가장 인기있는 하나입니다) 제어 흐름 라이브러리를 선택하는 것이 좋습니다 것입니다, 당신은 waterfall

async.parallel([ 
    function(callback){ 
     setTimeout(function(){ 
      callback(null, 'one'); 
     }, 200); 
    }, 
    function(callback){ 
     setTimeout(function(){ 
      callback(null, 'two'); 
     }, 100); 
    } 
], 
// optional callback 
function(err, results){ 
    // the results array will equal ['one','two'] even though 
    // the second function had a shorter timeout. 
}); 

가 (코드가에서 빌려 선택할 수 있습니다 비동기의 주요 웹 사이트). 따라서 중첩 된 함수간에 변수를 공유하려는 경우 최상위 레벨 인 DB.cityUpdateUpkeep에 정의 할 수 있으며 다른 중첩 된 함수에서도 사용할 수 있습니다. 그러나 언제든지 변수를 수정하면 나중에 실행되는 함수가 영향을받습니다.

그리고 중첩 된 함수는 얼마나 나쁜가요? 아무것도 nodejs 자연 (비동기 프로그래밍 모델), 당신은 그것과 함께 살고있다.

1

Q에서 콜백을 플랫 화하는 방법을 살펴보십시오 (코드가 더 좋을 것입니다). (ERR 그들이 의존하지있을 때

  • 동시에 비동기 호출을 실행합니다 (둥지 다른 사람에있는에서 당신을 절약 할) 때

    1. 반환 방법 초기 : 특정 예를 들어, 나는 메소드를 사용하여 리팩토링하는 것을 선호 . DB.cityGet 및 DB.iBuildings.find 알 - 코드 실행 속도뿐만 아니라)
    2. 기능을 만들고 둥지 (예 : 외부 참조한다 checkComplete)

    아래 내 리팩토링 :

    DB.cityUpdateUpkeep = function(cuid){ 
        /** @type {Array} */ 
        var buildings = null; 
        var city = null; 
        var checkComplete = function(){ 
         if (!city || !builings){ 
          return; 
         } 
         var income = city.resources.income; 
         var storage = city.resources.storage; 
         var stored = city.resources.stored; 
    
         for(var buildingID in buildings){ 
          var building = buildings[ buildingID ]; 
          var blueprint = DB.bBuildings[ building.buid ]; 
    
          if(blueprint.resources.income){ 
           income = Utils.sumObjects(income, blueprint.resources.income); 
          } 
    
          if(blueprint.resources.storage){ 
           storage = Utils.sumObjects(storage, blueprint.resources.storage); 
          } 
    
          if(blueprint.resources.stored){ 
           stored = Utils.sumObjects(stored, blueprint.resources.stored); 
          } 
         } 
    
         console.log("cuid: " + city._id + " income: " + income + " storage " + storage + " stored " + stored); 
    
        } 
        DB.cityGet(cuid, function(err, response){ 
         if (err){ 
          console.log("Couldn't get city"); 
          return; 
         } 
         city = response; 
         checkComplete(); 
        }); 
        DB.iBuildings.find({cuid:cuid}, function(err, cursor){ 
         if (err){ 
          console.log(err); 
          return; 
         } 
         cursor.toArray(function(err, response){ 
          if (err){ 
           console.log(err) 
           return; 
          } 
          buildings = response; 
          checkComplete(); 
         }); 
        }); 
    }); 
    
  • +0

    실제로 더 좋아 보입니다. cityUpdateUpkeep을 호출 할 때마다 checkComplete와 핸들러를 생성합니다. 아직도, 평행선에 +1.나는 범위를 알아 내는데 어려움을 겪었지만 이제는 그것을 보았고, 얼마나 단순한 지 간략하게 생각합니다 :)) – Discipol

    +0

    여러분은 checkComplete에 대해 옳았습니다. 단순히 기능 외부로 이동하십시오. 핸들러는 현대 javascript 엔진에서 정리해야합니다. 사실, 내가 이해하는 바에 따르면, checkComplete는 매번 재 할당되지 않을 것이지만 안전 할 수있는 것이 가장 좋습니다. – badunk