【问题标题】:A .then doesn't run after the promise gets resolved on AWS LambdaA .then 在 AWS Lambda 上解决承诺后不会运行
【发布时间】:2020-02-21 21:59:11
【问题描述】:

代码:

var promiseResolve, promiseReject;    

function iterateRules(rules, params, i = 0) {

    CWevents.putRule(rules[i], function(err, data) {    // This is an async function with a callback
        if (err) console.log(err); promiseReject(err)

        responses++
        params['Lambda_invoke']['SourceArns'].push(data.RuleArn)

        if(responses == rules.length){ promiseResolve("Success"); console.log("Resolved")} 
        // After two responses are confirmed, this if does run and I get the "Resolved"
    })
    i++
    if(i < rules.length){
        setTimeout( function(){
            iterateRules(params['CW_rules']['Rules'], params, i)
        }, 50)
    }
}

new Promise((resolve, reject) => {
    resolve() 
// This part is added solely for the code to make sense, it's taken out of a 
// bigger script and lots of unnecessary data is removed 
})
.then((Item) => {
            return new Promise((resolve, reject) => {
                promiseReject = reject;
                promiseResolve = resolve;
                iterateRules(params['CW_rules']['Rules'], params)
            })
}) .then((res) => {
        console.log("This ran")
   })

iterateRules 函数应该多次运行异步函数,并在获取最后一个响应时解析它调用的 Promise。 if(responses == rules.length) 确实按预期运行并在控制台中记录“已解决”。一切顺利,没有错误。

下面是这段代码的上下文,iterateRules 函数被执行,但后面的.then 没有被执行。如果我将resolve() 直接放入promise 中,它会执行。这个脚本可能有什么问题?我尝试单独运行一个看起来像这样的简单版本:

var res, rej;

function dude(){
    res()
}

new Promise((resolve, reject) => {
    res = resolve;
    dude()
}).then((dude) => {
    console.log("resolved")
})

而且它确实有效,所以我很困惑。什么可能导致问题?

【问题讨论】:

  • 我注意到的第一件事是你不需要使用Promise constructor antipattern
  • 这条线 new Promise((resolve, reject) =&gt; { resolve()}) 零意义?为什么你做出承诺然后立即解决?
  • 因为它是一个 300 行脚本的一部分,并且包含敏感数据、许多非默认功能,并且对于这种情况来说是不必要的。所以我用一个简单的resolve() 替换它,以使脚本有意义。
  • 哇,这段代码简直是一场异步噩梦……我不知道从哪里开始。 iterateRules 应该返回一个承诺吗?
  • 不,iterateRules 只是在解决所有请求时解决它调用的承诺。至少应该这样。

标签: javascript amazon-web-services asynchronous aws-lambda es6-promise


【解决方案1】:

我会让iterateRules() 返回一个承诺(因为它是异步的)。我还承诺CWevents.putRule() 函数,这样你就可以完成如下代码:

function iterateRules(rules, params) {
    return Promise.all(rules.map(rule => {
        return CWevents.putRule(rule)
    })).then((data) => {
        params['Lambda_invoke']['SourceArns'].push(data.RuleArn)
    })
}

那么您的 iterateRules 处理程序将变为:

iterateRules(rules,params).then(()=>{
    // Do something...
})

【讨论】:

  • 对于纯粹主义者来说,是的,我知道CWevents.putRule() 有一个简写形式,但如果您不了解(val) =&gt; {return val}(val) =&gt; val,它的可读性就会降低
  • 谢谢。我使用Promise.all() 实现了它,但它解决了问题并且看起来更整洁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2016-01-10
  • 2016-05-06
  • 2020-03-16
相关资源
最近更新 更多