Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 链接猫鼬承诺的语法_Javascript_Node.js_Mongodb_Mongoose_Promise - Fatal编程技术网

Javascript 链接猫鼬承诺的语法

Javascript 链接猫鼬承诺的语法,javascript,node.js,mongodb,mongoose,promise,Javascript,Node.js,Mongodb,Mongoose,Promise,我对使用Promises和MongoDB/Mongoose比较陌生,我正在尝试通过几个数据库查询将流链接成一个高效可靠的函数 我想知道我的最终功能是否是实现我想要的目标的一种良好和可靠的方式,或者是否有任何问题或任何可以改进的地方 程序如下: 1) 检查用户是否已经存在 usersSchema.findOne({ email: email }).then(res => { if(res==null){ // user does not exist }

我对使用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);
});
我仍在试图弄清楚这到底是如何工作的以及为什么工作的——函数返回一个承诺,而每个嵌套的承诺都返回一个承诺

我主要担心的是,有很多嵌套正在进行(是否有一种方法可以通过链接.then()回调而不是嵌套所有内容来实现这一点?),而且嵌套的承诺似乎没有错误捕获功能,尽管由于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);
});

为了避免缩进地狱,如果您从传递给承诺的
.then()
-方法的函数返回一个值,您可以将多个
.then()
链接为一个整洁的管道。请注意,您还可以返回一个具有挂起状态的承诺,然后该行中的下一个函数将在解析后执行

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)
  })
}

您原来的函数调用代码在这两种情况下都能正常工作。

谢谢,这两个都是很好的例子!我以前玩过async/await,但这有助于阐明它的用途!