在 then 回调中使用 await - 保留关键字“await”
Posted
技术标签:
【中文标题】在 then 回调中使用 await - 保留关键字“await”【英文标题】:Using await in then callback - the keyword 'await' is reserved 【发布时间】:2018-06-18 18:02:33 【问题描述】:在 node.js 中,我有一个数据库事务,我想在 then
回调中调用 async
方法,但我收到错误消息 the keyword 'await' is reserved
。
这是异步saveImage
函数:
const saveImage = async (parsedLink) =>
AWS.config.region = config.awsSettings.region;
AWS.config.accessKeyId = config.awsSettings.accessKeyId;
AWS.config.secretAccessKey = config.awsSettings.secretAccessKey;
const bucket = new AWS.S3(
params:
Bucket: config.awsSettings.images_bucket_name,
,
);
const currentDateString = new Date().toISOString().replace(/\:|\./g, '-');
const bodystream = new Buffer(parsedLink.imgUrl, 'binary');
const imageUrlDomain = parseDomain(parsedLink.linkUrl).domain;
const params =
Key: `$parsedLink.id/$imageUrlDomain_$currentDateString$parsedLink.imgType`,
ContentType: parsedLink.imageMime,
ContentEncoding: 'base64',
Body: bodystream,
;
const resultPromise = await bucket.upload(params).promise();
return resultPromise.Location;
;
如果我想使用saveImage
函数,我会收到错误消息。
module.exports.addTestObject = async (ctx) =>
const testObj = ctx.request.body;
try
switch (testObj.type)
case interestT.getType.link:
const knexTestObject = TestObject.knex();
transaction(knexTestObject, trx =>
TestObject.query(trx)
.insert(
interestDate: testObj.date,
)
.then(newInterest =>
// save image
if (parsedLink.saveImg)
parsedLink.imgUrl = await saveImage(testObj);
newInterest.$relatedQuery('linkInterestsRel', trx).insert(
linkHeader: testObj.linkHeader,
),
),
)
.then((linkInterest) =>
console.log(linkInterest);
)
.catch((err) =>
throw err;
);
break;
default:
break;
ctx.response.body = interestObj;
catch (err)
const statusCode = err.status || 400;
ctx.throw(statusCode, err.message);
;
【问题讨论】:
你只能在async
函数中使用await
,并且你的.then()
回调不是async
。
-> .then(async (newInterest) =>
@JonasW。谢谢,你能把它写成答案吗?然后我可以关闭这个问题。
呃,不要在 async
函数中使用 then
回调。
【参考方案1】:
常规的function
s 同步运行直到它们返回。因此,您不能在其中使用await
,因为您不能以同步方式等待异步事件。
javascript 也有 async function
s,它们看起来像常规函数,但在概念上完全不同:它们同步运行直到达到 await
,然后它们停止并在等待的 Promise 后继续解决。因此,它们不能同步返回结果,而是返回一个 Promise,然后在函数完成执行时解析。
因此您需要将您的函数转换为异步函数:
async function getUsername() // <-- async keyword here
return (await getUser()).name; // <-- await can be used inside
现在这也可以在 .then
回调中工作:
getUser().then(async function(user)
const friends = await getFriends(user);
// ...
)
但这在某种程度上将抽象异步函数与其底层的原始 Promise 混合在一起。如果你只是 await
Promise 而不是添加 .then
回调,代码会变得更具可读性:
(async function()
const user = await getUser();
const friends = await getFriends(user);
)();
具体问题可以改写为:
const linkInterest = await transaction(knexTestObject, async trx =>
const newInterest = await TestObject.query(trx)
.insert( interestDate: testObj.date, );
if (parsedLink.saveImg)
parsedLink.imgUrl = await saveImage(testObj);
await newInterest.$relatedQuery('linkInterestsRel', trx)
.insert( linkHeader: testObj.linkHeader, ),
);
【讨论】:
如果想使用await
进行查询,transaction
回调仍然需要是async function
(确实应该)。以上是关于在 then 回调中使用 await - 保留关键字“await”的主要内容,如果未能解决你的问题,请参考以下文章