Javascript 将对象推入对象数组

Javascript 将对象推入对象数组,javascript,node.js,mongoose,ecmascript-6,Javascript,Node.js,Mongoose,Ecmascript 6,问题: function saveAssetInDatabase(project, fileInformation) { return new Promise((reject, resolve) => { let uploaded_file = {} uploaded_file = fileInformation uploaded_file.file_type = 'asset' uploaded_file.displ

问题:

function saveAssetInDatabase(project, fileInformation) {
    return new Promise((reject, resolve) => {
        let uploaded_file = {}
        uploaded_file = fileInformation
        uploaded_file.file_type = 'asset'
        uploaded_file.display_name = fileInformation.originalname
        project.uploaded_files.push(uploaded_file)
        project.save()
    })
}
for(var i=0; i<req.files["sourceStrings"].length; i++) {
    // Unknown file format, let's save it as asset
    saveAssetInDatabase(project, fileInformation).then(result => {
        return res.status(200).send()
    }).catch(err => {
        logger.error(err)
        return res.status(500).send()
    })
}
我想通过将每个上传文件的文件信息写入我的数据库来跟踪我上传的文件。然而,当我上传2个文件时,它通常会在数据库中创建3个条目,当我上传6个文件时,它会创建更多的条目

我的数据库功能:

function saveAssetInDatabase(project, fileInformation) {
    return new Promise((reject, resolve) => {
        let uploaded_file = {}
        uploaded_file = fileInformation
        uploaded_file.file_type = 'asset'
        uploaded_file.display_name = fileInformation.originalname
        project.uploaded_files.push(uploaded_file)
        project.save()
    })
}
for(var i=0; i<req.files["sourceStrings"].length; i++) {
    // Unknown file format, let's save it as asset
    saveAssetInDatabase(project, fileInformation).then(result => {
        return res.status(200).send()
    }).catch(err => {
        logger.error(err)
        return res.status(500).send()
    })
}
调用函数的简化代码:

function saveAssetInDatabase(project, fileInformation) {
    return new Promise((reject, resolve) => {
        let uploaded_file = {}
        uploaded_file = fileInformation
        uploaded_file.file_type = 'asset'
        uploaded_file.display_name = fileInformation.originalname
        project.uploaded_files.push(uploaded_file)
        project.save()
    })
}
for(var i=0; i<req.files["sourceStrings"].length; i++) {
    // Unknown file format, let's save it as asset
    saveAssetInDatabase(project, fileInformation).then(result => {
        return res.status(200).send()
    }).catch(err => {
        logger.error(err)
        return res.status(500).send()
    })
}

for(var i=0;i问题

每次在for循环中创建一个承诺,然后发送该时间项目 对象。这不是正确的方式。每个承诺都已解决,您已将项目对象发送到DB,然后将其存储

例如,您有3个资产详细信息。 当运行第一个资产数据的第一个时间循环将存储在项目对象中并且承诺已解决时,您已将该时间项目发送到数据库存储它。此时间项目对象具有第一个资产详细信息

而运行第二个资产数据的第二个时间循环将与第一个资产数据和承诺一起存储在项目对象中,您已将该时间项目发送到数据库存储它。此时间项目对象具有第一个和第二个资产详细信息

而运行第三个资产数据的第三次循环将与第一个和第二个资产数据以及承诺一起存储在project对象中,您已将该时间项目发送到数据库中并将其存储。此时间项目对象具有第一个、第二个和第三个资产详细信息

因此,您必须在数据库中存储相同的数据

解决方案

您必须使用Promise.all。在数据库中存储项目数据后,解决所有assest的承诺

    // your DB function
    function saveAssetInDatabase(project, fileInformation) {
        return new Promise((resolve, reject) => {
            let uploaded_file = {}
            uploaded_file = fileInformation
            uploaded_file.file_type = 'asset'
            uploaded_file.display_name = fileInformation.originalname
            project.uploaded_files.push(uploaded_file)
            project.save();
            resolve();
        })
    }

    // calls function

    let promiseArray = [];
    for(var i=0; i<req.files["sourceStrings"].length; i++) {
        promiseArray.push(saveAssetInDatabase(project, fileInformation));
    }

    Promise.all(promiseArray).then(result => {
        return res.status(200).send();
    }).catch(err => {
        logger.error(err)
        return res.status(500).send()
    })
}
//您的数据库函数
函数saveAssetInDatabase(项目、文件信息){
返回新承诺((解决、拒绝)=>{
让上传的_文件={}
上传的文件=文件信息
上传的文件。文件类型='资产'
上传的\u file.display\u name=fileInformation.originalname
project.upload\u files.push(上传的\u文件)
project.save();
解决();
})
}
//调用函数
让promiseArray=[];
对于(var i=0;i{
返回res.status(200.send();
}).catch(错误=>{
记录器错误(err)
返回资源状态(500).send()
})
}

问题

每次在for循环中创建一个承诺,然后发送该时间项目 对象。这不是正确的方式。每个承诺都已解决,您已将项目对象发送到DB,然后将其存储

例如,您有3个资产详细信息。 当运行第一个资产数据的第一个时间循环将存储在项目对象中并且承诺已解决时,您已将该时间项目发送到数据库存储它。此时间项目对象具有第一个资产详细信息

而运行第二个资产数据的第二个时间循环将与第一个资产数据和承诺一起存储在项目对象中,您已将该时间项目发送到数据库存储它。此时间项目对象具有第一个和第二个资产详细信息

而运行第三个资产数据的第三次循环将与第一个和第二个资产数据以及承诺一起存储在project对象中,您已将该时间项目发送到数据库中并将其存储。此时间项目对象具有第一个、第二个和第三个资产详细信息

因此,您必须在数据库中存储相同的数据

解决方案

您必须使用Promise.all。在数据库中存储项目数据后,解决所有assest的承诺

    // your DB function
    function saveAssetInDatabase(project, fileInformation) {
        return new Promise((resolve, reject) => {
            let uploaded_file = {}
            uploaded_file = fileInformation
            uploaded_file.file_type = 'asset'
            uploaded_file.display_name = fileInformation.originalname
            project.uploaded_files.push(uploaded_file)
            project.save();
            resolve();
        })
    }

    // calls function

    let promiseArray = [];
    for(var i=0; i<req.files["sourceStrings"].length; i++) {
        promiseArray.push(saveAssetInDatabase(project, fileInformation));
    }

    Promise.all(promiseArray).then(result => {
        return res.status(200).send();
    }).catch(err => {
        logger.error(err)
        return res.status(500).send()
    })
}
//您的数据库函数
函数saveAssetInDatabase(项目、文件信息){
返回新承诺((解决、拒绝)=>{
让上传的_文件={}
上传的文件=文件信息
上传的文件。文件类型='资产'
上传的\u file.display\u name=fileInformation.originalname
project.upload\u files.push(上传的\u文件)
project.save();
解决();
})
}
//调用函数
让promiseArray=[];
对于(var i=0;i{
返回res.status(200.send();
}).catch(错误=>{
记录器错误(err)
返回资源状态(500).send()
})
}
如果我在mongoose网站上正确阅读了上的规范,那么保存的问题在于您总是重复使用原始项目,而不是应该包含最新状态的新保存的项目

因此,您实际上正在做的是:

project.files.push(file1);
// file1 is marked as new
project.save();
project.files.push(file2);
// file1 & file2 are marked as new 
// (the project doesn't know file1 has been saved already)
// ...
现在,这实际上带来了一些好处,因为您目前正在对每个文件进行保存,而您可以一次保存所有文件;)

我想最简单的方法是将project.save方法放在for循环之外,然后像这样更改第一个方法

function saveAssetInDatabase(project, fileInformation) {
    let uploaded_file = {};
    uploaded_file = fileInformation;
    uploaded_file.file_type = 'asset';
    uploaded_file.display_name = fileInformation.originalname;
    project.uploaded_files.push(uploaded_file);
}
将for循环更改为

function saveSourceString(project, req) {
    for(var i=0; i<req.files["sourceStrings"].length; i++) {
        // Unknown file format, let's save it as asset
        saveAssetInDatabase(project, fileInformation);
    }
    // save after all files were added
    return project.save().then(result => {
        return res.status(200).send()
      }).catch(err => {
        logger.error(err)
        return res.status(500).send()
      });
}
函数saveSourceString(项目,请求){
对于(var i=0;i如果我在mongoose网站上正确阅读了上的规范,那么保存的问题在于您总是重复使用原始项目,而不是应该包含最新状态的新保存的项目

因此,您实际上正在做的是:

project.files.push(file1);
// file1 is marked as new
project.save();
project.files.push(file2);
// file1 & file2 are marked as new 
// (the project doesn't know file1 has been saved already)
// ...
现在,这实际上带来了一些好处,因为您目前正在对每个文件进行保存,而您可以一次保存所有文件;)

我想最简单的方法是将project.save方法放在for循环之外,然后像这样更改第一个方法

function saveAssetInDatabase(project, fileInformation) {
    let uploaded_file = {};
    uploaded_file = fileInformation;
    uploaded_file.file_type = 'asset';
    uploaded_file.display_name = fileInformation.originalname;
    project.uploaded_files.push(uploaded_file);
}
将for循环更改为

function saveSourceString(project, req) {
    for(var i=0; i<req.files["sourceStrings"].length; i++) {
        // Unknown file format, let's save it as asset
        saveAssetInDatabase(project, fileInformation);
    }
    // save after all files were added
    return project.save().then(result => {
        return res.status(200).send()
      }).catch(err => {
        logger.error(err)
        return res.status(500).send()
      });
}
函数saveSourceString(项目,请求){

对于(var i=0;i)使用
req.files.sourceStrings
作为循环条件,但不在循环本身中使用它有什么意义?您总是立即保存相同的资产请确保您的req.files['sourseStrings']没有副本吗?@nem035使用了它,但这只是一个简化版本。我将它简化为相关部分。req.files.sourceStrings用于创建
fileInformation
使用
req.files.sourceStrings
作为循环条件但不在循环本身中使用它有什么意义?你总是在保存相同的内容