我完成了一个 Node 应用程序教程,然后返回使用 async/await 重写代码以更好地了解它是如何完成的。但是我有一个路由处理程序,如果不使用 promise 我就做不到:
getProfile: function(id){
return new Promise(function(resolve, reject){
Profile.findById(id, function(err, profile){
if (err){
reject(err)
return
}
resolve(profile.summary())
})
})
}
我重写为:
getProfile: async (req, res, next) => {
const profileId = req.params.id;
const profile = await Profile.findById(profileId);
res.status(200).json(profile)
}
编辑 2:好的,我也意识到我重写了:
create: function(params){
return new Promise(function(resolve, reject){
var password = params.password
params['password'] = bcrypt.hashSync(password, 10)
Profile.create(params, function(err, profile){
if (err){
reject(err)
return
}
resolve(profile.summary())
})
})
}
作为
newProfile: async (params, res, next) => {
const newProfile = new Profile(params);
const password = params.password
params['password'] = bcrypt.hashSync(password, 10)
const profile = await newProfile.save();
return profile.summary()
},
这很可能导致 jsonwebtokens 出现问题:<
我在使用 jsonwebtokens 时遇到问题的 API 端点:
var token = req.session.token
utils.JWT.verify(token, process.env.TOKEN_SECRET)
.then(function(decode){
return controllers.profile.getProfile(decode.id)
})
.then(function(profile){
res.json({
confirmation: 'success',
profile: profile
})
})
.catch(function(err){
res.json({
confirmation: 'fail',
message: 'Invalid Token'
})
})
}
异步代码适用于对/profile 路由的 GET 和 POST 请求,但在 API 捕获 block 中不断收到“无效 token ”消息。我对 promises 和异步代码都不熟悉,所以我确定现在有很多我不理解的地方。
所以我的问题是我如何重写以正确格式传递配置文件对象的 promise ?
完整文件:
Controller /ProfileController.js
var Profile = require('../models/Profile')
var Album = require('../models/Album')
var Promise = require('bluebird')
var bcrypt = require('bcryptjs')
module.exports = {
index: async (req, res, next) => {
const profiles = await Profile.find({});
const summaries = []
profiles.forEach(function(profile){
summaries.push(profile.summary())
})
res.status(200).json(summaries)
},
newProfile: async (params, res, next) => {
const newProfile = new Profile(params);
const password = params.password
params['password'] = bcrypt.hashSync(password, 10)
const profile = await newProfile.save();
return profile.summary()
},
getProfile: function(id){
return new Promise(function(resolve, reject){
Profile.findById(id, function(err, profile){
if (err){
reject(err)
return
}
resolve(profile.summary())
})
})
},
updateProfile: async (req, res, next) => {
const { profileId } = req.params;
const newProfile = req.body;
const result = await Profile.findByIdAndUpdate(profileId, newProfile);
res.status(200).json({success: true})
},
getProfileAlbums: async (req, res, next) => {
const profileId = req.params.id;
const profile = await Profile.findById(profileId);
},
newProfileAlbum: async (req, res, next) => {
const newAlbum = new Album(req.body);
console.log('newAlbum', newAlbum)
}
}
routes/profile.js:
var express = require('express');
const router = require('express-promise-router')();
const ProfileController = require('../controllers/ProfileController')
router.route('/')
.get(ProfileController.index)
.post(ProfileController.newProfile);
router.route('/:id')
.get(ProfileController.getProfile)
.patch(ProfileController.updateProfile);
router.route('/:id/album')
.get(ProfileController.getProfileAlbums)
.post(ProfileController.newProfileAlbum);
module.exports = router;
routes/account.js:
var express = require('express')
var router = express.Router()
var controllers = require('../controllers')
var bcrypt = require('bcryptjs')
var utils = require('../utils')
router.get('/:action', function(req, res, next){
var action = req.params.action
if (action == 'logout'){
req.session.reset()
res.json({
confirmation: 'success'
})
}
if (action == 'currentuser'){
if (req.session == null) {
res.json({
confirmation: 'success',
message: 'user not logged in'
})
return
}
if (req.session.token == null) {
res.json({
confirmation: 'success',
message: 'user not logged in'
})
return
}
var token = req.session.token
utils.JWT.verify(token, process.env.TOKEN_SECRET)
.then(function(decode){
return controllers.profile.getProfile(decode.id)
})
.then(function(profile){
res.json({
confirmation: 'success',
profile: profile
})
})
.catch(function(err){
res.json({
confirmation: 'fail',
message: 'Invalid Token'
})
})
}
})
router.post('/register', function(req, res, next){
var credentials = req.body
controllers.profile
.newProfile(credentials)
.then(function(profile){
var token = utils.JWT.sign({id: profile.id}, process.env.TOKEN_SECRET)
req.session.token = token
res.json({
confirmation: 'success',
profile: profile,
token: token
})
})
.catch(function(err){
res.json({
confirmation: 'fail',
message: err.message || err
})
})
})
router.post('/login', function(req, res, next){
var credentials = req.body
controllers.profile
.find({userName: credentials.userName}, true)
.then(function(profiles){
if (profiles.length == 0){
res.json({
confirmation: 'fail',
message: 'Profile not found'
})
return
}
var profile = profiles[0]
var passwordCorrect = bcrypt.compareSync(credentials.password, profile.password)
if (passwordCorrect == false){
res.json({
confirmation: 'fail',
message: 'Incorrect password'
})
return
}
var token = utils.JWT.sign({id: profile._id}, process.env.TOKEN_SECRET)
req.session.token = token
res.json({
confirmation: 'success',
profile: profile.summary(),
token: token
})
})
.catch(function(err){
res.json({
confirmation: 'fail',
message: err
})
})
})
module.exports = router
工具/JWT.js:
var jwt = require('jsonwebtoken')
var Promise = require('bluebird')
module.exports = {
sign: function(obj, secret){
return jwt.sign(obj, secret)
},
verify: function(token, secret){
return new Promise(function(resolve, reject){
jwt.verify(token, secret, function(err, decode){
if (err){
reject(err)
return
}
resolve(decode)
})
})
}
}
最佳答案
您不应该将其重写为 async
函数。这对于 Profile.findById
方法的 promise 来说完全没问题:
getProfile: function(id) {
return new Promise(function(resolve, reject){
Profile.findById(id, function(err, profile) {
if (err) reject(err);
else resolve(profile);
})
}).then(profile => profile.summary());
}
您可以重写 API 端点的代码以使用 async
/await
语法,但是:
async function(req, res, next) {
try {
const token = req.session.token
const decode = await utils.JWT.verify(token, process.env.TOKEN_SECRET);
const profile = await controllers.profile.getProfile(decode.id);
res.json({
confirmation: 'success',
profile: profile
});
} catch(err) {
console.error(err);
// maybe also call next(err)?
res.json({
confirmation: 'fail',
message: 'Invalid Token'
});
}
}
关于javascript - 使用 Jsonwebtokens 的 Promises 与 Async,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46108249/