在声明分配之前执行节点/ Mongoose模型创建

时间:2015-05-22 14:21:57

标签: node.js asynchronous mongoose

Facebook.create在fbUtils.getLongTermToken完成检索长期令牌之前执行。这在尝试创建用户时导致验证问题。我是否需要使用promises来管理这里发生的异步执行?

var userData = req.body;
userData.email = userData.email.toLowerCase();
userData.fbAuthToken = fbUtils.getLongTermToken(userData.fbAuthToken);

FacebookUser.create(userData, function (err, fbUser) {
    console.log(userData.fbAuthToken);
    if (err) {
        console.log(err.message);
        if (err.toString().indexOf('E11000') > -1) {
            err = new Error('Email already exists.');
        }
        res.status(400);
        return res.sendStatus({reason: err.toString()});
    } else {
        res.send('success');
    }
});

这是fbUtils.getLongTermToken的代码:

getLongTermToken: function (token) {
    var options = {
        host: 'graph.facebook.com',
        path: '/oauth/access_token?grant_type=fb_exchange_token'
        + '&client_id=' + CONSTANTS.FACEBOOK_APP_ID
        + '&client_secret=' + CONSTANTS.FACEBOOK_APP_SECRET
        + '&fb_exchange_token=' + token
    };
    var str = '';
    http.get(options, function (res) {

        res.on('data', function (chunk) {
            str += chunk;
        });

        res.on('end', function () {
            console.log(str);
            console.log(fbUtils.parseToken(str));
            return fbUtils.parseToken(str);
        });
    }).on('error', function(err) {
        console.log('longterm error: ' + err.message);
    });
    return str;

}

2 个答案:

答案 0 :(得分:1)

您还需要更新getLongTermToken以进行回调,这将在令牌检索完成时调用。例如:

getLongTermToken: function (token, cb) {
    var options = {
        host: 'graph.facebook.com',
        path: '/oauth/access_token?grant_type=fb_exchange_token'
        + '&client_id=' + CONSTANTS.FACEBOOK_APP_ID
        + '&client_secret=' + CONSTANTS.FACEBOOK_APP_SECRET
        + '&fb_exchange_token=' + token
    };
    var str = '';
    http.get(options, function (res) {

      res.on('data', function (chunk) {
        str += chunk;
      });

      res.on('end', function () {
        console.log(str);
        console.log(fbUtils.parseToken(str));
        return cb(fbUtils.parseToken(str));
      });
    }).on('error', function(err) {
        console.log('longterm error: ' + err.message);
    });
}

然后您需要更新您的调用代码以等待此令牌:

var userData = req.body;
userData.email = userData.email.toLowerCase();
fbUtils.getLongTermToken(userData.fbAuthToken, function (token) {
    userData.fbAuthToken = token;
    FacebookUser.create(userData, function (err, fbUser) {
        console.log(userData.fbAuthToken);
        if (err) {
            console.log(err.message);
            if (err.toString().indexOf('E11000') > -1) {
                err = new Error('Email already exists.');
            }
            res.status(400);
            return res.sendStatus({reason: err.toString()});
        } else {
            res.send('success');
        }
    });
});

答案 1 :(得分:0)

由于fbUtils.getLongTermToken是异步的,因此在检索并解析令牌后,应在其回调中调用Facebook.create

getLongTermToken: function (token) {
    var options = {
        host: 'graph.facebook.com',
        path: '/oauth/access_token?grant_type=fb_exchange_token'
        + '&client_id=' + CONSTANTS.FACEBOOK_APP_ID
        + '&client_secret=' + CONSTANTS.FACEBOOK_APP_SECRET
        + '&fb_exchange_token=' + token
    };
    var str = '';

    http.get(options, function (res) {

        res.on('data', function (chunk) {
            str += chunk;
        });

        res.on('end', function () {
            console.log(str);
            console.log(fbUtils.parseToken(str));
            var parsedToken = fbUtils.parseToken(str);

            // The earliest point where the token can be used
            Facebook.create(...);

            return parsedToken;
        });
    }).on('error', function(err) {
        console.log('longterm error: ' + err.message);
    });
    return str;

}