2017-10-15 179 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.