-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());
    })
}
4

3 回答 3

1

您循环正确,但问题是 JavaScript 没有为forbody 创建一个闭包。由于您在循环中i启动了异步操作,因此在异步操作完成并调用回调时, 的值已更改。

所以你必须立即在 for 循环中创建一个闭包,在闭包中存储你想要的值,然后在闭包中定义回调的同时调用异步操作。

for(var i = 0; i < resourcesArray.length; i++) {
  (function(i) {
    // Do work here with the value i
  })(i);
}
于 2016-07-19T15:29:57.930 回答
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) { ... }发生时,i等于resourcesArray.length因为迭代已经完成。这就是 JavaScriptvar声明变量的工作方式。使用forEach循环可确保范围始终包含resource您对该操作的期望。

或者,如果 ES6 没问题,那么您可以更改varletand 也可以解决问题,因为let-declared 变量使用词法范围,这意味着 for 循环块将始终包含预期值,i即使它在异步回调中使用。

于 2016-07-19T15:33:17.267 回答
-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
于 2016-07-19T15:23:45.353 回答