Javascript 如何确保fs.createWriteStream在函数继续之前完成;仅保存部分图像
我正在向API发出请求,以获取图像的路径。我想将此图像保存到mongoDB集合中的数据库中,这样用户就不需要不断发出API请求 我在向imagePath发出请求的地方设置了一些东西,并在响应中使用管道fs.createWriteStream() 然后在代码的后面,我使用我的模式使用这个文件创建一个“字符”。它可以工作,但只保存了图像的一小部分,就像前五分之一。在它继续之前,它还没有结束 我尝试使函数异步,然后在url请求之前使用wait。我也尝试过各种express/fs方法,比如writeFileSync(),但这些方法都不起作用 如何让文件在mongoDB启动之前完成编写Javascript 如何确保fs.createWriteStream在函数继续之前完成;仅保存部分图像,javascript,mongodb,express,fs,Javascript,Mongodb,Express,Fs,我正在向API发出请求,以获取图像的路径。我想将此图像保存到mongoDB集合中的数据库中,这样用户就不需要不断发出API请求 我在向imagePath发出请求的地方设置了一些东西,并在响应中使用管道fs.createWriteStream() 然后在代码的后面,我使用我的模式使用这个文件创建一个“字符”。它可以工作,但只保存了图像的一小部分,就像前五分之一。在它继续之前,它还没有结束 我尝试使函数异步,然后在url请求之前使用wait。我也尝试过各种express/fs方法,比如writeFi
let imagePath = req.body.characterObject.thumbnail.path + '.' + req.body.characterObject.thumbnail.extension;
let superPath = './uploads/marvelousImage.jpg';
let marvelousImage;
axios({
url: imagePath,
responseType: 'stream',
})
.then(response => {
marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
})
.catch(err => {
console.log(err)
});
User.findOne({ "username": "administrator"})
.then(user => {
let characterId = req.body.characterObject.id;
for(let i = 0; i < user.characters.length; i++) {
if(characterId == user.characters[i].id) {
return Promise.reject({
code: 422,
message: 'You already have this character!',
reason: "CharacterDuplicationError"
});
}
}
console.log(req.body.characterObject);
Character.create({
description: req.body.characterObject.description || 'bocho',
events: req.body.characterObject.events || 'lopo',
thumbnail: req.body.characterObject.thumbnail || 'goso',
name: req.body.characterObject.name || 'John Doe',
id: req.body.characterObject.id,
"image.data": fs.readFileSync(superPath),
"image.contentType": 'image/jpeg'
})
.then(char => {
console.log('lalala');
console.log(char);
user.characters.push(char);
user.save();
return res.status(201).json({message: "Character Added!"})
})
.catch(err => {
if(err.reason === "CharacterDuplicationError") {
return res.send(err);
}
})
})
});
让imagePath=req.body.characterObject.Thumboil.path+'.+req.body.characterObject.Thumboil.extension;
让超级路径='。/uploads/marvelousImage.jpg';
让美好的形象;
axios({
url:imagePath,
responseType:'流',
})
。然后(响应=>{
marvelousImage=response.data.pipe(fs.createWriteStream(超级路径));
})
.catch(错误=>{
console.log(错误)
});
User.findOne({“用户名”:“管理员”})
。然后(用户=>{
让characterId=req.body.characterObject.id;
for(设i=0;i{
console.log('lalala');
console.log(char);
user.characters.push(char);
user.save();
返回res.status(201.json)({message:“Character Added!”})
})
.catch(错误=>{
如果(err.reason==“characterReplicationError”){
返回res.send(err);
}
})
})
});
不清楚这是否是您的唯一问题,但这是问题之一
在此代码中:
.then(response => {
marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
})
承诺链没有等待管道完成读/写。为此,您需要从.then()
处理程序返回一个承诺,该处理程序在读/写操作完成时解析。您可以通过监听writeStream上的事件来实现这一点.pipe()
返回写流,以便我们可以使用该返回值设置事件处理程序,然后使用这些事件解析/拒绝我们返回的承诺。这将使承诺链在转到承诺链中的下一个.then()
之前等待流处理完成
.then(response => {
return new Promise((resolve, reject) => {
marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
marvelousImage.on('error', reject).on('close', resolve);
});
});
然后,我立即看到您在承诺链之外启动了数据库。这必须在承诺链中
.then(response => {
return new Promise((resolve, reject) => {
marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
marvelousImage.on('error', reject).on('close', resolve);
});
});
我试图将所有内容都放入承诺链中,并将其展平,并清理您的错误处理:
let imagePath = req.body.characterObject.thumbnail.path + '.' + req.body.characterObject.thumbnail.extension;
let superPath = './uploads/marvelousImage.jpg';
axios({
url: imagePath,
responseType: 'stream'
}).then(response => {
return new Promise((resolve, reject) => {
let marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
marvelousImage.on('error', reject).on('close', resolve);
});
}).then(() => {
return User.findOne({"username": "administrator"});
}).then(user => {
let characterId = req.body.characterObject.id;
for (let i = 0; i < user.characters.length; i++) {
if (characterId == user.characters[i].id) {
return Promise.reject({
code: 422,
message: 'You already have this character!',
reason: "CharacterDuplicationError"
});
}
}
console.log(req.body.characterObject);
return Character.create({
description: req.body.characterObject.description || 'bocho',
events: req.body.characterObject.events || 'lopo',
thumbnail: req.body.characterObject.thumbnail || 'goso',
name: req.body.characterObject.name || 'John Doe',
id: req.body.characterObject.id,
"image.data": fs.readFileSync(superPath),
"image.contentType": 'image/jpeg'
});
}).then(char => {
console.log('lalala');
console.log(char);
user.characters.push(char);
user.save();
return res.status(201).json({
message: "Character Added!"
})
}).catch(err => {
console.log(err);
if (err.reason === "CharacterDuplicationError") {
res.send(err);
} else {
res.sendStatus(500);
}
});
让imagePath=req.body.characterObject.thumbnail.path+'.+req.body.characterObject.thumbnail.extension;
让超级路径='。/uploads/marvelousImage.jpg';
axios({
url:imagePath,
响应类型:'stream'
})。然后(响应=>{
返回新承诺((解决、拒绝)=>{
让marvelousImage=response.data.pipe(fs.createWriteStream(superPath));
marvelousImage.on('error',reject.)。on('close',resolve);
});
}).然后(()=>{
返回User.findOne({“用户名”:“管理员”});
})。然后(用户=>{
让characterId=req.body.characterObject.id;
for(设i=0;i{
console.log('lalala');
console.log(char);
user.characters.push(char);
user.save();
返回res.status(201.json)({
信息:“添加字符!”
})
}).catch(错误=>{
控制台日志(err);
如果(err.reason==“characterReplicationError”){
res.send(err);
}否则{
res.sendStatus(500);
}
});
不清楚这是否是您的唯一问题,但这是问题之一
在此代码中:
.then(response => {
marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
})
承诺链没有等待管道完成读/写。为此,您需要从.then()
处理程序返回一个承诺,该处理程序在读/写操作完成时解析。您可以通过监听writeStream上的事件来实现这一点.pipe()
返回写流,以便我们可以使用该返回值设置事件处理程序,然后使用这些事件解析/拒绝我们返回的承诺。这将使承诺链在转到承诺链中的下一个.then()
之前等待流处理完成
.then(response => {
return new Promise((resolve, reject) => {
marvelousImage = response.data.pipe(fs.createWriteStream(superPath));
marvelousImage.on('error', reject).on('close', resolve);
});
});
然后,我立即看到您启动了数据库