Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.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_Express - Fatal编程技术网

Javascript 如何在承诺链中使用变量

Javascript 如何在承诺链中使用变量,javascript,node.js,mongodb,express,Javascript,Node.js,Mongodb,Express,我使用nodejs和expressframework以及mongodb/mongoose来存储我的数据 我有一个寄存器函数,它可以做4件事。创建用户,创建令牌,将令牌分配给用户,最后发送电子邮件 我最初使用回调来实现这一点,效果很好。我试图使用承诺,现在我已经要求蓝鸟做到这一点。但是,当一个承诺完成时,我需要在下一个承诺中使用返回的变量 注册功能 module.exports.register = function(req, res) { var input = req.body;

我使用nodejs和expressframework以及mongodb/mongoose来存储我的数据

我有一个寄存器函数,它可以做4件事。创建用户,创建令牌,将令牌分配给用户,最后发送电子邮件

我最初使用回调来实现这一点,效果很好。我试图使用承诺,现在我已经要求蓝鸟做到这一点。但是,当一个承诺完成时,我需要在下一个承诺中使用返回的变量

注册功能

module.exports.register = function(req, res) {

    var input = req.body;

    var newUser = new User ({

        username: input.username,
        email: input.email,
        password: input.password,
        active: false

    });

    var promise = newUser.save();

    promise.then(function(user) {

        return createToken('new', null, user._id);

    }).then(function(token) {

        user.tokens.push(token._id);

        return user.save();

    }).then(function(user) {

        //Do Email Stuff

    }).catch(function(err) {

        return res.json("Could Not Register");

    });
}
var createToken = function(type, expiry, userid) {

    var token = uuid.v4();

    return new Promise(function(resolve, reject) {

        var newToken = Token({

            type:type,
            token: token,
            expiry: expiry,
            user: userid

        });

        var promise = newToken.save();

        promise.then(function(token) {

            resolve(token);

        }).catch(function(err) {

            reject(err);

        });

    });

};
创建令牌功能

module.exports.register = function(req, res) {

    var input = req.body;

    var newUser = new User ({

        username: input.username,
        email: input.email,
        password: input.password,
        active: false

    });

    var promise = newUser.save();

    promise.then(function(user) {

        return createToken('new', null, user._id);

    }).then(function(token) {

        user.tokens.push(token._id);

        return user.save();

    }).then(function(user) {

        //Do Email Stuff

    }).catch(function(err) {

        return res.json("Could Not Register");

    });
}
var createToken = function(type, expiry, userid) {

    var token = uuid.v4();

    return new Promise(function(resolve, reject) {

        var newToken = Token({

            type:type,
            token: token,
            expiry: expiry,
            user: userid

        });

        var promise = newToken.save();

        promise.then(function(token) {

            resolve(token);

        }).catch(function(err) {

            reject(err);

        });

    });

};
所以在我做“user.tokens.push”的地方,它找不到用户。我在《蓝鸟报》上读到我可以用一种叫做绑定的东西?然后用“这个”。有人能告诉我怎么做吗

另外,如果每个承诺中都有错误,我希望catch方法是动态的。它不是“无法注册”,而是“无法保存用户”或“无法保存令牌”,具体取决于哪个承诺失败


如果有办法让它更干净,请告诉我。

在register函数的作用域中使用var来存储
user
的值以供以后使用,这并不丢脸

module.exports.register = function(req, res) {
    var input = req.body;
    var newUser = new User ({
        username: input.username,
        email: input.email,
        password: input.password,
        active: false
    });
    var sUser; // store user in this var
    newUser.save()
    .then(function(user) {
        sUser = user; // save value user to use later on
        return createToken('new', null, user._id);
    }).then(function(token) {
        sUser.tokens.push(token._id); // sUser is user, huzzah
        return sUser.save();
    }).then(function(user) {
        //Do Email Stuff
    }).catch(function(err) {
        // use the content of err to return a meaningful error
        return res.json("something more meaningful based on the content of err");
    });
}
您还应该避免createToken中的新Promise反模式

var createToken = function(type, expiry, userid) {
    var token = uuid.v4();
    var newToken = Token({
        type:type,
        token: token,
        expiry: expiry,
        user: userid
    });
    return newToken.save();
};
这将生成与代码相同的结果

另一种方法是将
user
发送到createToken函数,然后像这样重写代码

module.exports.register = function(req, res) {
    var input = req.body;
    var newUser = new User ({
        username: input.username,
        email: input.email,
        password: input.password,
        active: false
    });
    newUser.save()
    .then(function(user) {
        return createToken('new', null, user);
    }, function(err) { // optionally change errors to meaningful error messages
        throw "newUser.save failed";
    }).then(function(user) {
        //Do Email Stuff
        // you could throw "email failed" if there's an error
    }).catch(function(err) {
        // err could be "newUser.save failed", "newToken.save failed", "email failed"
        // use the content of err to return a meaningful error
        return res.json("something more meaningful based on the content of err");
    });
}

var createToken = function(type, expiry, user) {
    var token = uuid.v4();
    var newToken = Token({
        type:type,
        token: token,
        expiry: expiry,
        user: user._id
    });
    return newToken.save()
    .then(function(token) {
        user.tokens.push(token._id);
        return user.save();
    }) // you could add the following to make the errors suited to you
    .catch(function(err) {
        throw "newToken.save failed";
    });
};

您正在引用user.tokens.push,但代码示例中没有用户变量。也许这个例子不完整,或者你忘了检索用户?@shershen-我想你已经确定了问题的重点,注意到uve选择不推荐bluebird绑定功能?为什么?没有理由。仅仅使用纯js,因为我可以用一种方法来设置每种方法中的err值,然后承诺?你会一直使用承诺而不是回调吗?我认为这两种方法看起来都很可怕。我更新了答案,展示了如何将
err
设置为您想要的任何值。re:Promise vs callback,就个人而言,我不喜欢一个而不是另一个,所以你是说我可以在每个函数中添加“function(err){},然后设置err消息。你知道关于这方面的详细文章吗,因为我认为我不完全理解如何抛出错误。当你抛出时,它会作为err变量返回catch中吗?