javascript - 链接/嵌套承诺
问题描述
我正在做噩梦,试图链接 aws js sdk。目前我有以下内容(省略了任何参数来删除箔条,这些调用是独立工作的,所以可以安全地假设它们是正确的)
function deploy() {
return sts.assumeRole().promise()
.then(() => {
return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
AWS.config.update({
credentials: {
accessKeyId: data.Credentials.AccessKeyId,
secretAccessKey: data.Credentials.SecretAccessKey,
sessionToken: data.Credentials.SessionToken
}
});
resolve();
})
.then(() => {
fsPromise.readFile(packageLocation).then(() => {
return s3.upload().promise();
});
});
}).then(() => {
return ebs.createApplicationVersion().promise();
}).then(() => {
return ebs.createEnvironment().promise();
});
};
如果我then
一个一个地运行它们以便它工作,但是当我一起运行它们时,createApplicationVersion
调用失败,因为upload
它没有工作,因为它试图在assumeRole
完成之前上传。我假设...
我显然做错了什么,但我不清楚是什么。
解决方案
使用 Promise 比必要的复杂得多。请记住,then
(and catch
and finally
)返回基于其处理程序返回的新承诺。new Promise
在then
(or catch
or finally
) 处理程序中几乎从不需要;只需返回您将使用(一个值或另一个承诺)解决该承诺的任何内容,以及由then
et 返回的承诺。人。将解决它。
AWS.config.update()
如果我假设是同步的,那条链应该是这样的:
function deploy() {
return sts.assumeRole().promise()
.then(() => {
AWS.config.update();
})
.then(() => fsPromise.readFile(packageLocation))
.then(() => s3.upload().promise())
.then(() => ebs.createApplicationVersion().promise())
.then(() => ebs.createEnvironment().promise());
}
该链中的每一步都将等待上一步完成。
如果你不想deploy
用 的实现值来实现它的承诺ebs.createEnvironment().promise()
,那么添加一个最终then
处理程序:
.then(() => ebs.createEnvironment().promise())
.then(() => { });
}
(我假设您想为以下示例执行此操作。)
或者像这样 ifAWS.config.update()
是异步的并返回一个承诺:
function deploy() {
return sts.assumeRole().promise()
.then(() => AWS.config.update())
.then(() => fsPromise.readFile(packageLocation))
.then(() => s3.upload().promise())
.then(() => ebs.createApplicationVersion().promise())
.then(() => ebs.createEnvironment().promise())
.then(() => { });
}
或者,当然,在任何相对较新的 Node.js 版本中(我从fsPromise
一般上下文中猜测这是 Node.js),您可以使用一个async
函数:
async function deploy() {
await sts.assumeRole().promise();
await AWS.config.update(); // Or without `await` if it is synchronous and doesn't return a promise
await fsPromise.readFile(packageLocation);
await s3.upload().promise();
await ebs.createApplicationVersion().promise();
await ebs.createEnvironment().promise();
}
关于此代码的旁注,以及您在评论中发布的类似代码:
return new Promise((resolve, reject) => {
AWS.config.update({
credentials: {
accessKeyId: data.Credentials.AccessKeyId,
secretAccessKey: data.Credentials.SecretAccessKey,
sessionToken: data.Credentials.SessionToken
}
});
resolve();
})
没有理由在new Promise
那里使用。它不会将调用转换AWS.config.update
为异步调用或类似的调用。如果由于某种原因你需要一个承诺(在这种情况下你不需要,AKAICT),你会使用Promise.resolve
:
AWS.config.update(/*...*/);
return Promise.resolve();
但同样,这里不需要。请记住,promise 仅提供一种观察异步过程结果的方法,它们不会使过程异步。(他们实际上使异步的唯一事情是观察结果。)
推荐阅读
- postgresql - TypeORM PostgreSQL 语句超时
- javascript - 如何检查 div 是否可见,然后使用 jQuery 在除此 div 之外的任何其他位置单击时将其隐藏?
- javascript - 我需要传递从 api 调用获得的 id 来调用另一个 api 调用
- ansible - Ansible:如何从列表中连接字典的属性?
- perl - Perl Net::SFTP::Foreign 断开连接不关闭连接
- sql - 如何从表中查找缺失值
- python - 地址范围的最小值、最大值和步长
- python - alpha 和 beta 大于 1 的指数平滑
- image - 容器内的码头工人不再工作
- python-3.x - 代码未编译 - 无法找出问题