簡體   English   中英

鏈接貓鼬諾言的語法

[英]Syntax for chaining mongoose promises

我對使用Promises和MongoDB / Mongoose相對較新,並且正在嘗試將流通過多個數據庫查詢鏈接到一個高效且可靠的功能中。

我想知道我的最終職能是實現我想要的目標的一種良好而可靠的方法,或者是否有任何問題或可以改進的地方。

流程如下:

1)檢查用戶是否已經存在

usersSchema.findOne({
    email: email
}).then(res => {
    if(res==null){
        // user does not exist
    }
}).catch(err => {});

2)將新用戶添加到數據庫

var new_user = new usersSchema({ email: email });
new_user.save().then(res => {
    // new user id is res._id
}).catch(err => {});

3)向用戶分配免費的促銷代碼

codeSchema.findOneAndUpdate({
    used: false,
    user_id: true
},{
    used: true,
    user_id: mongoose.Types.ObjectId(res._id)
}).then(res => {
    // user's code is res.code
}).catch(err => {});

顯然,每個查詢都需要按順序執行,因此在對如何執行此操作進行了大量研究和實驗之后,我將查詢合並到以下功能中,到目前為止,該功能似乎還可以正常工作:

function signup(email){
    // check email isn't already signed up
    return usersSchema.findOne({
        email: email
    }).then(res => {
        if(res==null){
            // add to schema
            var new_user = new usersSchema({ email: email });
            // insert new user
            return new_user.save().then(res => {
                var result = parse_result(res);
                // assign a code
                return codesSchema.findOneAndUpdate({
                    used: false,
                    user_id: true
                },{
                    used: true,
                    user_id: mongoose.Types.ObjectId(result._id),
                });
            });
        }else{
            return 'The user already exists';
        }
    });
}

signup('test@test.com').then(res => {
    console.log('success, your code is '+res.code);
}).catch(err => {
    console.log(err);
});

我仍在努力弄清楚它的工作方式和原因-該函數正在返回一個Promise,而每個嵌套的Promise都在返回一個Promise。

我主要擔心的是正在進行大量嵌套(也許可以通過鏈接.then()回調而不是嵌套所有內容來實現此目的),並且嵌套的promises似乎沒有捕獲錯誤,盡管由於signup()函數本身是一個承諾,因此似乎可以捕獲所有錯誤。

是否有任何有關該主題的知識的人能夠確認我的過程看起來是否良好和可靠? 謝謝!

您的代碼可以通過這種方式進行改進

function signup(email){
    // check email isn't already signed up
    return usersSchema.findOne({
        email: email
    }).then(res => {
        if(res==null){            // add to schema
            var new_user = new usersSchema({ email: email });
            // insert new user
            return new_user.save()
        }else{
            return Promise.reject(new Error('The user already exists'));
        }
    })
    .then(res => {
        var result = parse_result(res);
        // assign a code
        return codesSchema.findOneAndUpdate({used: false,user_id: true},{used: true,user_id: mongoose.Types.ObjectId(result._id),});
    });

}

signup('test@test.com').then(res => {
    console.log('success, your code is '+res.code);
}).catch(err => {
    console.log(err);
});

為了避免縮進,如果您從傳遞給Promise的.then()方法的函數中返回一個值,則可以將多個.then()為整潔的管道。 請注意,您還可以返回狀態為待處理的Promise,然后在解決后,將執行行中的下一個函數。

function signup (email) {
  return usersSchema.findOne({
    email: email
  }).then(res => {
    if (res) throw 'The user already exists'
    var new_user = new usersSchema({ email: email })
    return new_user.save()
  }).then(res => {
    var result = parse_result(res)
    return codesSchema.findOneAndUpdate({
      used: false,
      user_id: true
    },{
      used: true,
      user_id: mongoose.Types.ObjectId(result._id)
    })
  })
}

更好的是,如果您有可能使用async/await (Node v7.6或更高版本),您的代碼可能看起來像普通的阻塞代碼:

async function signup (email) {
  let user = await usersSchema.findOne({ email: email })
  if (user) throw 'The user already exists'
  let new_user = await new usersSchema({ email: email }).save()
  let result = parse_result(new_user)
  return codesSchema.findOneAndUpdate({
    used: false,
    user_id: true
  },{
    used: true,
    user_id: mongoose.Types.ObjectId(result._id)
  })
}

您的原始函數調用代碼無需更改就可以同時使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM