【问题标题】:setInterval and wait for certain conditionssetInterval 并等待某些条件
【发布时间】:2017-08-14 13:36:30
【问题描述】:

我想做的事情在node js中可能做不到,但在我放弃之前我想得到其他意见。

我有一个正在执行产品设置的线程。为了论证起见,让我们称其为“主”线程。我希望在产品设置期间可能发生的所有错误都被“主”线程捕获。如果设置成功,那么我不希望“主”线程在我知道设置成功之前完成。

产品设置过程中的一个步骤涉及在客户的 AWS 账户中创建 CloudFormation 堆栈。执行此操作的 AWS 函数是 createStack。这个函数只是开始创建堆栈的过程。如果你使用 await 调用这个函数,那么创建堆栈的过程在你得到返回值后仍然会运行。

还有另一个名为 describeStacks 的 AWS CloudFormation 函数,我可以使用它来了解创建的进展情况。我不能重复调用这个方法(在调用之间不使用很大的间隔),因为 AWS 对我调用方法的频率有限制。

我希望能够每分钟调用一次此函数来检查堆栈创建的进度,直到我可以确定设置成功或失败。但至关重要的是,我还希望“主”线程等到成功或失败发生。

这在节点 js 中可能吗?我是节点 js 的新手。请随时告诉我我在滥用它并且我以错误的方式思考问题。我怀疑我是。

解决方案:这是为我解决问题的代码。感谢托马拉克

function checkStackCreationProgress(params) {
    return new Promise( (resolve, reject) => {
        const intervalId = setInterval( async () => {
            try {
                const result = await checkProgress(params);

                switch(result.status) {
                    case 'IN_PROGRESS': break; //do nothing
                    case 'COMPLETE': clearInterval(intervalId); resolve(result); break;
                    case 'FAILED': clearInterval(intervalId); reject(result); break;
                }
            }
            catch(error) {
                clearInterval(intervalId);
                reject(error);
            }
        },
        60000);
    })
    .then( () => {
        return;
    })
    .catch(error => {
        throw new SetupFailedError(`Failed to create ...`, error);
    });
}

在设置成功或失败之前,该函数不会返回

【问题讨论】:

    标签: node.js


    【解决方案1】:

    如果你使用await调用这个函数,那么在你得到返回值后,创建堆栈的过程仍然会运行。

    不要用await 调用它,这会阻塞线程。

    异步函数返回 Promises,您可以将它们链接起来并同时做其他事情。

    所以不是

    try {
        var result = await createStack({some: params));
        // work with result
    } catch (ex) {
        // handle error
    }
    

    createStack({some: params)).then(function (result) {
        // work with result
    }).catch(function (error) {
        // handle error
    });
    

    第二种形式是非阻塞的,你可以同时做任何类型的工作。例如:

    var checking = setInterval(function () {
        // check/output for the stack status...
    }, 60000)
    
    createStack({some: params)).then(function (result) {
        clearInterval(checking);
    
        // work with result
    }).catch(function (error) {
        clearInterval(checking);
    
        // handle error
    });
    
    console.log("Stack is being created, hang on...");
    

    【讨论】:

    • 感谢您的回复。我不相信这会做我想要的。我需要在 setInterval (describeStacks) 中调用的函数也返回一个 Promise,我需要根据这个 Promise 检查结束条件。此处抛出的任何错误都无法在 setInterval 之外捕获。我错了吗?
    • 好吧,setInterval() 只是概述了您可以在单个节点线程中并行执行所有这些操作的一种方式。在 createStack() 运行时,没有什么能阻止您使用更多的 Promise。我只是假设createStack() 返回操作的结果,describeStacks() 仅用于报告进度,所以我保持简单。
    • 这里有多篇文章解释了如何实现“重试直到成功”——带有承诺的模式。 Here's onehere's another,如果你环顾四周,你会发现更多。具体实现会因使用的库而有所不同,但可以做到,而且并不像起初看起来那么难。
    • 这是其中的一部分,是的。 :) 这就是我给你指点的原因。我已经成功地使用心理调试来引导您从一个没有任何代码的问题中找到您的问题的解决方案,而我从未使用过的框架;我认为这构成了“接受”。
    • @SiLaf 您可以使用您使用的代码发布您自己的答案,这可能对将来的某人有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    相关资源
    最近更新 更多