Javascript 正确的循环实现
我已经编写了一些代码来将swagger 1文档转换为swagger 2。 我将转换方法指向数组中的多个资源。 我发现它没有正确执行,并在调试器中看到它一直跳到我的数组(大小为34)的末尾。如何确保它正确地循环我的代码Javascript 正确的循环实现,javascript,node.js,callback,order-of-execution,Javascript,Node.js,Callback,Order Of Execution,我已经编写了一些代码来将swagger 1文档转换为swagger 2。 我将转换方法指向数组中的多个资源。 我发现它没有正确执行,并在调试器中看到它一直跳到我的数组(大小为34)的末尾。如何确保它正确地循环我的代码 for(var i = 0; i < resourcesArray.length; i++) { Converter.convert({ from: 'swagger_1', to: 'swagger_2', sourc
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());
})
}
for(var i=0;i
这可能是因为在for
循环中有一个异步调用。您需要为每次迭代冻结i
的值。您可以为此使用closure()
。如果要跟踪所有迭代何时完成,可以保留一个计数器:
var计数器=resourcesArray.length;
对于(var i=0;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
(功能(参考资料,i){
转换器({
摘自:《大摇大摆1》,
致:“招摇过市2”,
资料来源:'http://example/“+资源
},函数(错误,已转换){
console.log(资源);
//[可选]用伪值填充缺少的字段
已转换。fillMissing();
//[可选]验证转换的规范
var fileName=resources+'.json';
fs.writeFileSync(文件名,converted.stringify());
计数器--;
如果(counter循环正确,那么问题是JavaScript不会为主体创建一个闭包。因为您正在循环中启动一个异步操作,i
的值在异步操作完成并调用回调时发生了变化
因此,您必须在for循环中立即创建一个闭包,在闭包中存储所需的值,然后调用异步操作,同时在闭包中定义回调
for(var i = 0; i < resourcesArray.length; i++) {
(function(i) {
// Do work here with the value i
})(i);
}
for(var i=0;i
您已成为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());
});
});
问题是,当异步回调函数(err,converted){…}
发生时,i
等于resourcesArray.length
,因为迭代已经完成。这就是JavaScriptvar
声明变量的工作方式。使用forEach
循环可确保作用域始终包含该操作所需的资源
或者,如果ES6没有问题,那么您可以将var
更改为let
,这也可以解决问题,因为let
声明的变量使用词法作用域,这意味着for循环块将始终包含i
的预期值,即使它在异步回调中使用。就是这样…for循环的作用…它在整个数组中迭代执行内部的内容。回调发生在一段时间之后,并且不能保证顺序正确。如果ES6是可接受的,那么,for(让i=0;i
也可以工作。