2017-10-15 180 views
0

我正在AWS Lambda函数(节点4.3运行时)中运行以下代码。 Promise.all似乎过早返回,因为deleteSnapshot操作未运行。我对Node.js比较陌生,所以我肯定我在这里错过了一些明显的东西。但是它是什么?Promise.all似乎过早返回。我在这里错过了什么?

EC2.describeSnapshots(searchParams).promise().then((data) => { 
    Promise.all(data.Snapshots.map((snapshot) => { 
     var deleteParams = {SnapshotId: snapshot.SnapshotId}; 
     console.log('Deleting ' + snapshot.SnapshotId + ' pertaining to AMI ' + event.detail.requestParameters.imageId); 
     return EC2.deleteSnapshot(deleteParams).promise(); 
    })).then(context.done()); 
}); 

回答

1

的问题是,你立即调用context.done(),然后通过任何返回到Promise.all().then()。这不是你想要或打算做的。您需要将函数引用传递给.then(),而不是调用context.done()的结果。你可以解决这个问题是这样的:

EC2.describeSnapshots(searchParams).promise().then((data) => { 
    return Promise.all(data.Snapshots.map((snapshot) => { 
     var deleteParams = {SnapshotId: snapshot.SnapshotId}; 
     console.log('Deleting ' + snapshot.SnapshotId + ' pertaining to AMI ' + event.detail.requestParameters.imageId); 
     return EC2.deleteSnapshot(deleteParams).promise(); 
    })).then(() => context.done()); // <== Note change here 
}); 

要解释一下,当你有这样的代码:

Promise.all(...).then(context.done()) 

也与此类似:

let temp = context.done(); 
Promise.all(...).then(temp); 

所以,你可以清楚地看到你打电话context.done()的方式太早。相反,您需要将context.done()放在某种函数包装器中,以便您可以将该包装函数引用传递给.then()。实际上有多种方式可以做到这一点 - 我使用上面的箭头功能展示,但它也可以用.bind()完成,如

})).then(context.done.bind(context)); 
1

Promise.all()返回承诺。您需要从then()中返回该承诺,否则第一个then()返回undefined,context.done()将过早地调用。

EC2.describeSnapshots(searchParams).promise().then((data) => { 
    return Promise.all(data.Snapshots.map((snapshot) => { 
    // etc.