2016-07-19 2 views
-2

필자는 swagger 1 문서를 swagger 2로 변환하는 코드를 작성했습니다. 변환 방법을 배열의 여러 리소스로 지정합니다. 내가 찾은 것은 올바르게 실행되지 않고 크기가 34 인 배열의 끝까지 디버거에서 점프하는 것을 보았습니다. 코드를 통해 올바르게 반복되도록하려면 어떻게해야합니까?올바른 루프 구현

for(var i = 0; i < resourcesArray.length; i++) { 
    Converter.convert({ 
     from: 'swagger_1', 
     to: 'swagger_2', 
     source: 'http://example/' + resourcesArray[i] 
    }, function (err, converted) { 
     console.log(resourcesArray[i]); 
     // [Optional] Fill missing fields with dummy values 
     converted.fillMissing(); 

     // [Optional] Validate converted spec 
     var fileName = resourcesArray[i] + '.json'; 
     fs.writeFileSync(fileName, converted.stringify()); 
    }) 
} 
+0

... for for for 루프는 ... 내부의 내용을 실행하는 전체 배열을 반복합니다. 콜백 (callback)은 얼마 후 발생하며 정확한 순서로 보장되지는 않습니다. –

답변

1

JavaScript 범위 지정 규칙의 희생이 있습니다. 이 시도 :

resourcesArray.forEach(function (resource) { 
    Converter.convert({ 
     from: 'swagger_1', 
     to: 'swagger_2', 
     source: 'http://example/' + resource 
    }, function (err, converted) { 
     console.log(resource); 
     // [Optional] Fill missing fields with dummy values 
     converted.fillMissing(); 

     // [Optional] Validate converted spec 
     var fileName = resource + '.json'; 
     fs.writeFileSync(fileName, converted.stringify()); 
    }); 
}); 

문제는 반복이 이미 완료하기 때문에 비동기 콜백 function (err, converted) { ... }가 발생 시간, iresourcesArray.length 동일이었다. 그것이 JavaScript var이 선언 된 변수가 작동하는 방법입니다. forEach 루프를 사용하면 범위에 항상 해당 작업에 대해 기대하는 resource이 포함됩니다. ES6 괜찮 경우

또는, 당신은 letvar을 변경할 수 있으며, let -declared 변수는 루프 블록에 대한 항상 심지어 i의 기대 값이 포함됩니다 즉, 어휘 범위 지정을 사용하기 때문에 그 또한 문제를 해결할 것 비동기 콜백 내에서 사용되는 경우

+0

이것은 나를 위해 물건을 지 웁니다. 감사! – user3221287

-2

for 루프 내에 비동기 호출이 있기 때문에 상황이 발생할 수 있습니다. 반복 할 때마다 i의 값을 고정해야합니다. 이 경우 closure()을 사용할 수 있습니다. 모든 반복 작업이 완료된 시점을 추적하려는 경우 카운터를 유지할 수 있습니다. var counter = resourcesArray.length; for (var i = 0; i < resourcesArray.length; i ++) { var resources = resourcesArray [i]; 당신은 제대로 루핑

(function(resources, i){ 
    Converter.convert({ 
     from: 'swagger_1', 
     to: 'swagger_2', 
     source: 'http://example/' + resources 
    }, function (err, converted) { 
     console.log(resources); 
     // [Optional] Fill missing fields with dummy values 
     converted.fillMissing(); 

     // [Optional] Validate converted spec 
     var fileName = resources + '.json'; 
     fs.writeFileSync(fileName, converted.stringify()); 

     counter--; 
     if(counter <= 0) 
     { 
      //next(); 
     } 
    }) 
    })(resources, i);  
}//for 
1

그러나 문제는 자바 스크립트 for 몸 폐쇄를 생성하지 않습니다. 루프 내에서 비동기 작업을 시작하기 때문에 비동기 작업이 완료되고 콜백이 호출 될 때까지 i의 값이 변경되었습니다.

그래서 for 루프 내에서 즉시 클로저를 만들고 클로저 내에 원하는 값을 저장 한 다음 클로저 내에서 콜백을 정의하면서 비동기 작업을 호출해야합니다.

for(var i = 0; i < resourcesArray.length; i++) { 
    (function(i) { 
    // Do work here with the value i 
    })(i); 
} 
+0

ES6가 허용되면 'for (let i = 0; i