【问题标题】:Embedding a Sequelize promise into a javascript async/await chain将 Sequelize Promise 嵌入到 javascript async/await 链中
【发布时间】: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) => {

谢谢大家。

【问题讨论】:

    标签: javascript node.js promise async-await sequelize.js


    【解决方案1】:

    删除所有不必要的IIFEIIAFEreturn awaitPromise 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) => { 回调。但实际上你不应该混合使用 thenawait 语法,而是让外部函数也使用 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 只是可以是 awaited 的值,但您实际上并不严格需要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
        })
    

    【讨论】:

    • 你昨天去哪儿了?你会为我节省几个小时无用的研究。但说真的,非常感谢。我遵循的逻辑有点奇怪,因为我必须阅读其中一个表格两次,但是您的第一个建议效果很好,并使代码更具可读性。我很惊讶这样的情况不会更频繁地发生。您应该在某个地方发布您的出色建议,而不仅仅是在这里。
    猜你喜欢
    • 1970-01-01
    • 2019-08-11
    • 2018-03-24
    • 2018-07-10
    • 1970-01-01
    • 2021-05-13
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多