我已经创建了以下代码,但是如果findOneAndUpdate
找到结果,我似乎无法弄清楚如何更新图像,并且在put_form_url之前似乎正在执行result.save
。如何实现这样的功能,如果它存在,它将更新所有属性并将新图像上传到s3,如果不存在,它将创建一个带有s3上传的新对象。
router.post('/:id/:name/:birth/:country/:image', function(req, res, next) {
var params = req.params;
var accessHeader = req.headers;
process.env.AWS_ACCESS_KEY_ID=''
process.env.AWS_SECRET_ACCESS_KEY=''
AWS.config.region = 'eu-west-1';
var s3 = new AWS.S3();
User.findOneAndUpdate({"_id": params.id}, {$set:{"name": params.name, "birthday": params.birth, "country": params.country}}, {new: true}, function(error, result) {
if (!error) {
// If the document doesn't exist
if (!result) {
// Create it
put_from_url(params.image, new Date().toString, function(err, res) {
result = new User({
_id: params.id,
name: params.name,
birthday: new Date(params.birth),
country: params.country,
image: "url" + params.id
});
});
}
// Save the document
result.save(function(error) {
if (!error) {
res.json({ message: 'User created!' });
} else {
res.send(err);
}
});
}
});
});
上传功能
function put_from_url(url, key, callback) {
request({
url: url,
encoding: null
}, function(err, res, body) {
if (err)
return callback(err, res);
uploader.putObject({
Bucket: "",
Key: "/" + key,
ContentType: res.headers['content-type'],
ContentLength: res.headers['content-length'],
Body: body // buffer
}, callback);
})
}
答案 0 :(得分:0)
好的,似乎你有两个问题。
因此,在任何一种情况下,您都必须存储图像,所以为什么不先做更新图像然后更新/插入用户或反之亦然。我个人会选择前者。
router.post('/:id/:name/:birth/:country/:image', function(req, res, next) {
var params = req.params;
var accessHeader = req.headers;
process.env.AWS_ACCESS_KEY_ID=''
process.env.AWS_SECRET_ACCESS_KEY=''
AWS.config.region = 'eu-west-1';
var s3 = new AWS.S3();
put_from_url(params.image, params.id, function(err, res) {
result = new User({
_id: params.id,
name: params.name,
birthday: new Date(params.birth),
country: params.country,
image: "url" + params.id
});
// Save the document
result.save(function(error) {
if (!error) {
res.json({ message: 'User created!' });
} else {
res.send(err);
}
});
});
很少有注意事项,对于您使用日期的密钥,我只是使用了id,以便稍后可以使用新图像进行更新。可以使用唯一键来使用和更新s3对象。如果您想要保留旧图像副本,最好使用像params.id/(new Date().toString)
这样的密钥,这样旧的图像就不会被覆盖
其次,如果基于_id的对象存在,则保存函数固有地更新,否则它会创建一个新的。
肯定会,javascript本质上是异步的,这意味着如果一个代码占用太长时间,它将执行下一个语句。当你调用s3时,它的I / O调用将尝试将图像上传到s3并将被处理,同时你的下一行代码将在你的情况下执行result.save。
有两种方法。 I>在前一次调用的回调中包装下一个调用。并且更好和更优越的ii>使用承诺。
Promise是一种未来事件,您可以告诉上传到s3 然后保存到数据库中。
承诺几乎没有什么学习曲线,但它很棒,干净而且真的很有帮助。 q是一个这样的承诺模块。