gpt4 book ai didi

javascript - 在 Node.js 中使用 Q Promise 循环

转载 作者:太空宇宙 更新时间:2023-11-04 03:08:09 25 4
gpt4 key购买 nike

我对来自java世界的js和node非常陌生。我根据我正在编写的真实程序编写了一个测试程序。它在 Node.js 程序中使用 Q 库。

for 循环仅作用于数组中的最后一项。就像所有其他 Q.promises 都丢失了。

我的输出是:注册ELB注销ELB恢复ASG 4启动实例4恢复ASG 4启动实例4恢复ASG 4启动实例4恢复ASG 4启动实例4自动关闭完成。

正如我所期望的那样:

简历ASG 1启动实例1恢复ASG 2启动实例2恢复ASG 3启动实例3恢复ASG 4启动实例4注册ELB注销ELB自动关闭完成。

  1. 循环中发生了什么? promise 是否会落空?

  2. 为什么在我的第一个 .then() 之前发生 registerELB 和 de-registerELB

    var Q = require('q'); varstartInstances = [];

    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;
    }

最佳答案

这是一个 for 循环和循环内任何异步操作的典型问题。由于 for 循环内的异步操作在 for 循环完成后的一段时间才完成,因此当任何异步操作完成时,for 循环内设置的任何变量都将具有循环末尾的值。

在您的特定情况下,somedata 变量在这里是一个问题。通常,您可以通过使用闭包来解决此问题,以便每次调用异步操作都有自己的函数,因此它自己的状态在异步操作完成之前唯一存在。

在我看来,您可能还存在其他同步问题,因为您的 for 循环正在并行运行您的所有操作,并且您的内部异步操作和您正在解决的外部 promise 之间没有链接,所以我怀疑这里也存在其他问题。

但是,如果您只是将 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();
};

此外,您是否意识到您的内部 promise (在 .forEach() 循环内)根本与外部 promise 没有链接?那么,在 .forEach() 循环中的内部 promise 完成之前,getInstances() 就会解决它的 promise ?这对我来说看起来很糟糕。我不知 Prop 体要推荐什么,因为我不知道哪些操作要并行运行,哪些操作应该串行运行。您可能需要执行一个 Promise.all() 来收集 for 循环中的所有 promise ,然后使用它来解决您的外部 promise 。

关于javascript - 在 Node.js 中使用 Q Promise 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33003831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com