承诺问题 - .then() 没有被调用?

Posted

技术标签:

【中文标题】承诺问题 - .then() 没有被调用?【英文标题】:Promise problems - .then() not getting called? 【发布时间】:2016-06-02 12:28:54 【问题描述】:

我有两个需要按特定顺序运行的 Sequelize 查询,第一个创建一个模型,第二个从一个数组创建多个模型。它的工作原理是先插入obj1,然后插入事务数组,但是最终的“then()”似乎没有被调用……我做错了什么?

var fn = function addTransaction(transaction) 
     return new Promise(function() 
          return Transaction.create(transaction,  fields: [ 'Id', 'Name' ]);
     
;

var transactions = [...]; //array of transaction objects

Model1.create(obj1,  fields: [ 'Id', 'Name' ,'Description' ]).then(function() 

    var actions = transactions.map(fn);
    var results = Promise.all(actions).then(function(data) 
        return Promise.all(data.map(fn));
    );
    results.then(function() 
        console.log("Done?"); //not getting called
    );

).catch(function(err) 
    console.log(err);
);

【问题讨论】:

【参考方案1】:

addTransaction() 永远不会解决它创建的承诺。您创建了一个外部承诺并返回它,但从不解决它。您至少必须为该回调声明一个 resolve 参数,然后在某处调用 resolve()

但是,如果Transaction.create() 已经返回了一个承诺,那么您可以将addTransaction() 更改为:

var fn = function addTransaction(transaction) 
     return Transaction.create(transaction,  fields: [ 'Id', 'Name' ]);
;

还不清楚为什么您使用相同的fn 来处理每个事务产生的transactions 数组和data 数组。从逻辑的角度来看,这似乎有点奇怪。您确定这是编写代码的正确方法吗?为了让我们帮助您设计这部分代码,您必须通过在第一个事务数组上调用fn 来解释更多关于您要完成的工作,然后再对结果进行解释。 .

【讨论】:

哦,这很好。传递给Promise 构造函数的函数必须至少接受resolve 参数。 我尝试删除外部 Promise,但现在当它尝试创建模型时出现“非空违规”。 var fn = 代码来自另一个堆栈溢出答案:***.com/questions/31413749/… by Benjamin Gruenbaum @meanrims - 听起来您只是没有正确处理您的数据库。如果您可以在您的答案中添加正确的数据库操作顺序,我们可以轻松地帮助您使用 Promise 正确执行该操作,但我不知道您的数据库,因此无法帮助您修复原始数据库代码。本杰明的答案包含一个fn,它创建了一个承诺并解决了它,这是你的代码没有做的事情。但是,如果Transaction.create() 已经返回了自己的承诺,您可以返回(正如本杰明的回答所说)。 @meanrims - 而且,正如我的回答所说,您已经尝试在两个事务上运行相同的 fn 函数,然后是创建这些事务的结果,这看起来是错误的。在编码中很少有这样的事情是正确的。您可能需要备份大约 5 个步骤,并准确解释您要对数据库执行的操作,并描述您想要执行的操作的确切顺序和顺序。然后,我们可以通过承诺帮助您实现这一目标。 @jfriend00 db代码只是一个Sequelize模型定义,除了create()调用保存到db不需要其他代码【参考方案2】:

我不确定这是否能完全解决您的问题,但我认为您缺少return

...
return results.then(function() 
    console.log("Done?"); //not getting called
);
...

没有它,Model1.create 承诺将在 results 完成之前解决。

【讨论】:

我已经尝试过了,不幸的是它没有任何区别:(

以上是关于承诺问题 - .then() 没有被调用?的主要内容,如果未能解决你的问题,请参考以下文章

获取 Express API/Mongoose 调用后承诺不触发 .then()

在没有 this 的情况下在 fetch 承诺中调用函数

打破承诺链并根据链中被破坏(拒绝)的步骤调用函数

执行 .Then() 承诺 NodeJS

打破承诺链 - 停止执行下一个“then”

如何编写测试用例来覆盖承诺链中所有嵌套的“then”回调