繁体   English   中英

为什么 JS 承诺不适用于猫鼬?

[英]Why is JS promise not working with mongoose?

var mongoose = require('mongoose');
import es6Promise from 'es6-promise';
mongoose.Promise = es6Promise.Promise;
const follow = (followerID, toFollowId, cb) => { //REVISE only update
    User.update(
        { _id: toFollowId},
        {$push: {usersFollowing: followerID}},
        function(err){
            if (err){
                cb(true);
            } else {
                User.findByIdAndUpdate(
                    followerID,
                    {$push: {usersBeingFollowed: toFollowId}},
                    {safe: true, new: true},
                    function(err, model){
                        if (err){
                            cb(true);
                        } else {
                            cb(null, model);
                        }
                    }
                )
            }
        }
    )
}

const unfollow = (unfollowerId, toUnfollowId, cb) => { //REVISE only update
    User.update(
        { _id: toUnfollowId},
        {$pull: {usersFollowing: unfollowerId}}).then(
        function(err){
            if (err){
                return  cb(true);
            } else {
                User.findByIdAndUpdate(
                    unfollowerId,
                    {$pull: {usersBeingFollowed: toUnfollowId}},
                    {safe: true, new: true},
                    function(err, model){
                        if (err){
                            cb(true);
                        } else {
                            cb(null, model)
                        }
                    }
                )
            }
        })
}

我的跟随功能,它不使用承诺工作正常。 我尝试编辑我的取消关注功能以作为承诺工作,但它不起作用。 从 ES5 开始我就没有接触过 JS,但我承诺的理解是我只是将回调移动到 .then() 中并称之为一天。 我在这里缺少什么?

如果不传递回调函数,Mongoose 查询update方法将不会执行。 update文档中说明

该操作仅在传递回调时执行。 要在没有回调的情况下强制执行,我们必须首先调用update() ,然后使用exec()方法执行它。

所以将.exec()添加到链中,这也将返回一个成熟的承诺。

promise 的then方法有两个回调函数,第二个会在出错时调用,所以你必须拆分成功和失败代码。 为了保持一致,您应该完全切换到使用 Promise,并放弃传统的回调模式。 所以unfollow函数本身也应该返回一个 promise:

const unfollow = (unfollowerId, toUnfollowId) =>
    User.update(
        { _id: toUnfollowId },
        { $pull: { usersFollowing: unfollowerId } }
    ).exec()
    .then( _ =>
        User.findByIdAndUpdate(
            unfollowerId,
            { $pull: { usersBeingFollowed: toUnfollowId } },
            { safe: true, new: true }
        ).exec()
    );

你会称之为:

unfollow(unfollowerId, toUnfollowId).then( model => {
    // success
}, err => {
    // failure
});

我只是将回调移动到.then()并称它为一天。 我在这里缺少什么?

回调约定也会发生变化。 虽然节点回调有(err, result)参数,但 Promise 使用两种不同的回调——一种用于实现,一种用于拒绝——它们只传递一个参数。

虽然理论上你可以做到

User.update(…).then(function(_) {
    User.findByIdAndUpdate(…);
}, function(err){
    cb(true);
});

那将是一种可怕的做法。 为了利用promises真正力量,您需要返回链接它们。 在你的情况下,那将是

function unfollow(unfollowerId, toUnfollowId) {
//                                          ^ no more callback
    return User.update(
//  ^^^^^^ return the result of the `then` call
        { _id: toUnfollowId},
        {$pull: {usersFollowing: unfollowerId}}
    ).then(_ => {
        return User.findByIdAndUpdate(
//      ^^^^^^ just return the promise
            unfollowerId,
            {$pull: {usersBeingFollowed: toUnfollowId}},
            {safe: true, new: true}
//          that you get when no longer passing a callback
        );
    });
}

通过不传递任何错误回调,拒绝将自动沿链冒泡,您无需关心明确转发所有错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM