Javascript 在node.js中使用Q承诺循环
我对来自java世界的js和node非常陌生。我根据我正在编写的真实程序编写了一个测试程序。它在node.js程序中使用Q库 for循环仅作用于数组中的最后一项。。这就像所有其他的承诺都失去了一样 我的输出是: 注册数据库 登记处 简历ASG 4 启动实例4 简历ASG 4 启动实例4 简历ASG 4 启动实例4 简历ASG 4 启动实例4 自动关机完成 如我所料: 简历ASG 1 已启动实例1 简历ASG 2 启动实例2 简历ASG 3 启动实例3 简历ASG 4 启动实例4 注册数据库 登记处 自动关机完成Javascript 在node.js中使用Q承诺循环,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,我对来自java世界的js和node非常陌生。我根据我正在编写的真实程序编写了一个测试程序。它在node.js程序中使用Q库 for循环仅作用于数组中的最后一项。。这就像所有其他的承诺都失去了一样 我的输出是: 注册数据库 登记处 简历ASG 4 启动实例4 简历ASG 4 启动实例4 简历ASG 4 启动实例4 简历ASG 4 启动实例4 自动关机完成 如我所料: 简历ASG 1 已启动实例1 简历ASG 2 启动实例2 简历ASG 3 启动实例3 简历ASG 4 启动实例4 注册数据库 登记
test();
function test() {
getInstances()
.then(function(data) {
var promise = Q.defer();
for(var x = 0; x < data.length; x++) {
var somedata = data[x];
console.log(somedata);
startOrStop(somedata)
.then(function (updateStatus) {
var promiseinner = Q.defer();
console.log(somedata);
if(updateStatus == 'start') {
return Q.nfcall(resumeASG, somedata)
.then(Q.nfcall(startInstance, somedata));
} else if(updateStatus == 'stop') {
return Q.nfcall(suspendASG, somedata)
.then(Q.nfcall(stopInstance, somedata));
}
promiseinner.resolve('complete');
return promiseinner.promise;
})
}
promise.resolve('successful');
return promise.promise;
}, function(error) {
console.log('Failed to get instance data ' + error);
//context.fail();
}).then(function(data) {
return registerELB();
}, function(error) {
console.log('Failed to Re-register ELB ' + error);
//context.fail();
}).then(function(data) {
console.log('autoshutdown complete.')
//context.succeed(data);
}, function(error) {
console.log('autoshutdown failed to complete. ' + error)
//context.fail();
}).done();
};
function getInstances() {
var promise = Q.defer();
startedInstances.push(1);
startedInstances.push(2);
startedInstances.push(3);
startedInstances.push(4);
promise.resolve(startedInstances);
return promise.promise;
}
function suspendASG (asg) {
var promise = Q.defer();
console.log('suspendASG ' + asg);
promise.resolve(asg);
return promise.promise;
}
function resumeASG (asg) {
var promise = Q.defer();
console.log('resumeASG ' + asg);
promise.resolve(asg);
return promise.promise;
}
function registerELB() {
var promise = Q.defer();
console.log('registerELB ');
console.log('de-registerELB ');
promise.resolve('success elb');
return promise.promise;
}
function startInstance(instanceId) {
var promise = Q.defer();
console.log('started instance ' + instanceId);
promise.resolve(instanceId);
return promise.promise;
}
function stopInstance(instanceId) {
var promise = Q.defer();
console.log('stopped instance ' + instanceId);
promise.resolve(instanceId);
return promise.promise;
}
function startOrStop (instance) {
var promise = Q.defer();
promise.resolve('start');
return promise.promise;
}
test();
功能测试(){
getInstances()
.then(功能(数据){
var promise=Q.defer();
对于(var x=0;x
这是一个典型的问题,即
for
循环和循环内的任何异步操作。由于for
循环中的异步操作在for
循环完成后的一段时间内完成,因此在for
循环中设置的任何变量在任何异步操作完成时都将在循环的末尾具有值
在您的特定情况下,somedata
变量在这里是一个问题。通常,您可以通过使用闭包来解决这个问题,这样异步操作的每次调用都有自己的函数,从而有自己的状态,直到异步操作完成为止
在我看来,您可能还存在其他同步问题,因为您的for
循环并行运行所有操作,并且您的内部异步操作与您要解决的外部承诺之间没有联系,因此我怀疑这里也存在其他问题
但是,如果您只是将for
循环更改为.forEach()
循环,那么循环的每个调用都将有其自己的唯一状态。老实说,我不能说这段代码中没有其他问题(因为我没有办法测试它),但这至少可以解决与for
循环相关的一个问题:
test();
function test() {
getInstances()
.then(function(data) {
var promise = Q.defer();
// -------- Change made here -------------
// change for loop to .forEach() loop here
// to create closure so your async operations
// each can access their own data
data.forEach(function(somedata) {
console.log(somedata);
startOrStop(somedata)
.then(function (updateStatus) {
var promiseinner = Q.defer();
console.log(somedata);
if(updateStatus == 'start') {
return Q.nfcall(resumeASG, somedata)
.then(Q.nfcall(startInstance, somedata));
} else if(updateStatus == 'stop') {
return Q.nfcall(suspendASG, somedata)
.then(Q.nfcall(stopInstance, somedata));
}
promiseinner.resolve('complete');
return promiseinner.promise;
})
});
promise.resolve('successful');
return promise.promise;
}, function(error) {
console.log('Failed to get instance data ' + error);
//context.fail();
}).then(function(data) {
return registerELB();
}, function(error) {
console.log('Failed to Re-register ELB ' + error);
//context.fail();
}).then(function(data) {
console.log('autoshutdown complete.')
//context.succeed(data);
}, function(error) {
console.log('autoshutdown failed to complete. ' + error)
//context.fail();
}).done();
};
另外,您是否意识到您的内部承诺(在
.forEach()
循环中)根本没有链接到外部承诺?那么,getInstances()
将在.forEach()
循环中的内部承诺完成之前很久解决它的承诺?我觉得这个破了。我不知道该推荐什么,因为我不知道哪些操作要并行运行,哪些操作应该串联运行。您可能需要执行一个Promise.all()
来收集for
循环中的所有承诺,然后使用它来解析外部承诺。这是for
循环和循环内任何异步操作的经典问题。由于for
循环中的异步操作在for
循环完成后的一段时间内完成,因此在for
循环中设置的任何变量在任何异步操作完成时都将在循环的末尾具有值
在您的特殊情况下