2017-07-01 82 views
0

问题:物品推入对象数组

我想通过一个多上传每个上传的文件写入fileinformation到我的数据库来跟踪我上传的文件。但是,当我上传2个文件时,通常会在数据库中创建3个条目,而当我上传6个文件时,它会创建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() 
    }) 
} 

我想这有什么错我的数据库功能,因为它会导致复制文件条目。我在这里做错了什么?一个文件应该得到一个条目。

+1

使用'req.files.sourceStrings'的一点是什么?作为循环条件,但不在循环内部使用它?您现在总是保存相同的资产 – nem035

+0

请确保您的req.files ['sourseStrings']没有dublicates? – Vasi

+0

@ nem035它被使用,但这只是一个简化版本。我把它分解到相关部分。 req.files.sourceStrings用于创建'fileInformation' – kentor

回答

1

如果我读model.save规格正确的猫鼬的网站,你保存的问题是,而你总是重用原来的项目,而不是新保存的项目应包含最新的状态。

所以你基本上是这样做的:

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) 
// ... 

现在,这实际上带来了相当一些优势,因为你正在一个做保存每个文件,同时可以为您节省一次所有文件;)

我想最简单的方法就是放置该项目。保存方法你以外的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() 
     }); 
} 

注意project.save()会返回一个承诺,用包含新保存project参数。如果您希望稍后操作此对象,请确保您已保存文件,而不是像您至今所做的那样保存未保存的模型

1

问题

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

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

虽然运行第二个资产数据的第二个时间循环将存储在具有第一个资产数据的项目对象中,并且承诺解决,但您已将该时间项目发送到您的数据库存储中。这次项目对象具有第一和第二资产细节。

虽然第三次循环运行第三项资产数据将存储在具有第一和第二资产数据的项目对象中,并且承诺解决,您已将该时间项目发送到您的数据库存储中。这次项目对象具有第一,第二和第三资产细节。

因此,您的数据库中存储了相同的数据。

解决方案

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

// 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() 
    }) 
} 
+0

'promiseArray。(saveAssetInDatabase(project,fileInformation));'是一个错字还是这种'.push'的某种ES6语法? – kentor

+0

对不起,这是我的错误。我会纠正它。 – Vasi

+0

更改了它。它是否有用? – Vasi