如何在 Model.find( obj , callback) 上传播回调承诺值?

Posted

技术标签:

【中文标题】如何在 Model.find( obj , callback) 上传播回调承诺值?【英文标题】:How to propagate callback promise value on Model.find( obj , callback)? 【发布时间】:2016-03-01 23:44:36 【问题描述】:

好的,我正在努力解决这个问题。在过去的一周里,我花了很多时间试图弄清楚如何完成这项工作。我学习了promises 并做了一些很酷的东西——我很喜欢它。但是,我无法完成这项工作。

我正在使用 Mongoose Model.find() 方法。此方法接收两个参数:将用于查询的object 和将接收(error, data) 对象的callback 函数。我正在调用.find 并传递findUser 函数。

UserModel.find(userObj, findUser)
            .then(userFound, createUser);

findUser 内部,我正在创建一个Promise 并解决或拒绝它。

var findUser = function(err, data) 
    var p1 = new Promise( function (resolve, reject) 
        if (data.length) 
            console.log('Resolved on findUser');
            resolve();
         else 
            console.log('Rejected on findUser');
            reject();
        
    );
;

但是,无论findUser 发生什么,都会调用成功回调。在控制台上,我可以看到如下内容:

Rejected on findUser
Resolved on find
var userFound = function () 
    console.log('Resolved on find');
;

var createUser = function () 
    console.log('Rejected on find');

如何将承诺值从 findUser 传播到 .find

【问题讨论】:

我不知道Model.find 是如何工作的,但是您如何期望它知道您在findUser 回调中创建的Promise 发生了什么?至少,你必须return Promise 而不是仅仅声明它,对吧? 这就是我问的原因。不知道。马上试试。我已将其更改为返回新的 Promise。结果相同。 好的,你可能想尝试像这样链接:UserModel.find(userObj).then(findUser),但要让findUser 是 Promise-resolution 样式并且只接受 (data) 而不是 (err, data)。 【参考方案1】:

你可以试试这样的。代码中的所有更改都已注释。

// Remove err argument
var findUser = function(data) 
    // Instead of creating a new Promise, 
    // we return a value to resolve
    // or throw a value to reject.
    if (data.length) 
        console.log('Resolved on findUser');
        // Resolve this Promise with data.
        return data;
     else 
        var reason = 'Rejected on findUser';
        console.log(reason);
        // Reject this Promise with reason.
        throw reason;
    
;

// Function gets data passed to it.
var userFound = function(data) 
    console.log('Resolved on find');
;

// Function gets reason passed to it.
var createUser = function(reason) 
    console.log('Rejected on find');
;

// Promises will chain and propagate errors as necessary.
UserModel.find(userObj)
.then(findUser)
.then(userFound)
.catch(createUser);

【讨论】:

哇,它运行良好!谢谢。一个问题,如果你不介意的话。我知道 Model.find() 将一个函数作为第二个参数,该函数将被发送 2 个参数,第一个是错误对象。此代码如何将第一个参数作为数据发送? @Rodmentou Promises 的一大优点是errdata 之间不再有卷积。我们不再使用一个函数来混淆地处理两者,而是对其进行简化并具有两个函数,一个用于data,一个用于err。成功时,Model.find Promise 会说“好的,我们成功了,所以我们只需要使用数据调用成功回调,忽略错误回调”,所以findUserErr 永远不会被调用,findUser 会。如果出现错误,则会发生完全相反的事情。因此,我们只需要一个参数,即数据。 非常感谢。你让我很快乐。周*。 @Rodmentou 很高兴为您提供帮助。

以上是关于如何在 Model.find( obj , callback) 上传播回调承诺值?的主要内容,如果未能解决你的问题,请参考以下文章

Mongo Model.find条件不工作

如何设计链式 Model.find() 函数?

使用 Modell::find(array()) 时如何在 Laravel 中分页

Mongoose - 不能在 post findOneAndUpdate 钩子中调用 model.find()

Mongoose - 不能在 post findOneAndUpdate 钩子中调用 model.find()

Model.find 返回相同的对象引用