将 Sequelize Promise 嵌入到 javascript async/await 链中
Posted
技术标签:
【中文标题】将 Sequelize Promise 嵌入到 javascript async/await 链中【英文标题】:Embedding a Sequelize promise into a javascript async/await chain 【发布时间】:2019-12-30 23:06:42 【问题描述】:我正在尝试在现有异步/等待链中使用 Sequelize 承诺。 Sequelize 将所有内容作为承诺返回。我对 promises 和 async/await 不熟悉 所以我把它当作一种学习经验。请对我多一些耐心。
我的逻辑是这样的:
如果前一个'.then'中的行不存在
创建一个新行并提取新的 id
否则
从之前的 '.then' 中提取 id 值
所以现在我有一个 WORKING 代码块(如下),来自研究了许多优秀的 SO 示例。我想使用所有匿名函数,因为恕我直言,它使它更容易阅读。 (是的,有争议的一点,但现在我想尝试使用匿名函数。
有 三个 嵌套的返回语句似乎很奇怪。有没有办法将这段代码重写为更简洁,但只使用匿名函数?
yourTable.findAll( ...)
.then( (data) =>
// more code
)
.then( (data) =>
// more code
)
.then( (data) =>
if ( !Array.isArray(data) || !data.length )
// if record does NOT exist
return (async function ()
return await
(function ()
return new Promise( resolve =>
myTable.create( ........
).then( (result) =>
resolve(result._id);
)
)
)();
)()
/* we had to create one, so we return the *NEW* _id value */
else
/* we found one, so we just return the pre-existing _id value */
return data[0]._id ;
)
.then( (data) =>
// more code
)
.then( (data) =>
谢谢大家。
【问题讨论】:
【参考方案1】:删除所有不必要的IIFE、IIAFE、return await
和Promise
constructor antipattern:
if (!Array.isArray(data) || !data.length)
// if record does NOT exist
const result = await myTable.create( ........ );
return result._id; // we had to create one, so we return the *NEW* _id value
else
return data[0]._id; // we found one, so we just return the pre-existing _id value
【讨论】:
这是我尝试的第一件事,我得到了回复:“SyntaxError: await is only valid in async function” 当然,您当然需要对您的then
函数使用async (data) =>
回调。但实际上你不应该混合使用 then
和 await
语法,而是让外部函数也使用 async
/await
- 你能告诉我们更多代码吗?
或者如果你不想使用await
,它应该是if
块中的一个简单的return myTable.create(…).then(result => result._id);
。
"宁可做外部函数" - 好的,我注意了...!我添加了更多代码,但实际上并没有太多其他内容。
您可能应该从const data = await yourTable.findAll( ...); // more code
等开始。然后对于if
/else
,当您不能只使用return
时,分配给变量(或使用条件运算符)。将所有这些放在 async
函数中(或者,如果它已经在函数中,请添加 async
关键字)。【参考方案2】:
Promise 只是可以是 await
ed 的值,但您实际上并不严格需要到 await
它们,特别是如果您的周围结构没有使用 async
/@987654324 @。你可以这样写:
yourTable.findAll( /* ... */ )
.then((data) =>
if (!Array.isArray(data) || !data.length)
// We need to create one, return the new ID
return myTable.create( /* ... */ )
.then((result) => result._id)
else
// We found one, return the existing ID
return data[0]._id
)
如果您从 .then()
中返回 Promise,它将成为父链的一部分,这可能正是您想要的。
如果您真的想使用async
/await
,那么我建议您翻转逻辑并在您的快乐路径被计算后做更大的工作:
yourTable.findAll( /* ... */ )
.then(async (data) =>
if (data && data.length) return data[0]._id
const result = await myTable.create( /* ... */ )
return result._id
)
【讨论】:
你昨天去哪儿了?你会为我节省几个小时无用的研究。但说真的,非常感谢。我遵循的逻辑有点奇怪,因为我必须阅读其中一个表格两次,但是您的第一个建议效果很好,并使代码更具可读性。我很惊讶这样的情况不会更频繁地发生。您应该在某个地方发布您的出色建议,而不仅仅是在这里。以上是关于将 Sequelize Promise 嵌入到 javascript async/await 链中的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法使用 Sequelize 一次将多个嵌入式模型保存在数据库中
Node.js,ORM框架,Sequelize,入门及增、删、改、查代码案例
Sequelize与async联合使用关于warning:a promise was created but was not returned from it的思考