簡體   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