简体   繁体   English

有没有办法将此Promises调用重构为“最佳编码实践”版本?

[英]Is there a way to refactor this Promises calls into a “best coding practices” version?

My code works fine, I just want to continue solving this search feature with good coding practices. 我的代码工作正常,我只想继续通过良好的编码习惯来解决此搜索功能。 I feel like I am repeating the same code too many times. 我觉得我重复相同的代码太多次了。 I have two different types of objects "programs" and "rentals" if user selected one of both in the search menu I want to search My DB only for the specified object, however if he selects both or neither I want to execute both search functions. 如果用户在搜索菜单中选择了两者之一,则我有两种类型的对象“程序”和“出租”:我只想为指定的对象搜索“我的数据库”,但是如果他选择了两者或都不选择,则我想执行两个搜索功能。 In order to achieve this I have a conditional if which checks for those search options, if only one is selected I will execute the respective find() on the respective Schema, 为了实现这一点,我有条件确定是否检查那些搜索选项,如果仅选择一个,我将在相应的Schema上执行相应的find(),

if((queryObj.selectedSearchObjectType.indexOf("rentals") > -1))
  {
     let foundRentalsByTitle = await Promise.all(titleSplited.map((value) =>
               getRentalsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
           ));
      searchResults.rentals = searchResults.rentals.concat(foundRentalsByTitle);
   }

However as you may notice I am repeating the same code 4 times just to achieve this, I want to make good coding practices therefore I think this looks ugly and uneficient. 但是,您可能会注意到,为了达到这一目的,我重复了4次相同的代码,我想制定良好的编码习惯,因此,我认为这样做看起来很丑陋且效率低下。

if(queryObj.title) //If we have a title seacrh
        {
            queryObj.title = queryObj.title.trim();
            const titleSplited = queryObj.title.split(' ');//transform it to an array

            if(titleSplited.length > 0)
            {
                // Check if selectedSearchObjectType is defined to execute queryes selectively
                if(queryObj.selectedSearchObjectType)
                {
                    // Check if selectedSearchObjectType contains 'rentals' in order to add the result to finalResults Array 
                    if((queryObj.selectedSearchObjectType.indexOf("rentals") > -1))
                    {
                        let foundRentalsByTitle = await Promise.all(titleSplited.map((value) =>
                            getRentalsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
                        ));
                        searchResults.rentals = searchResults.rentals.concat(foundRentalsByTitle);
                    }

                    // Check if selectedSearchObjectType contains 'programs' in order to add the result to finalResults Array 
                    if((queryObj.selectedSearchObjectType.indexOf("programs") > -1))
                    {
                        let foundProgramsByTitle = await Promise.all(titleSplited.map((value) =>
                            getRentalsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
                        ));
                        searchResults.programs = searchResults.programs.concat(foundProgramsByTitle);
                    }
                }else{
                    //If no selectedSearchObjectType was selected then execute both
                    let foundProgramsByTitle = await Promise.all(titleSplited.map((value) =>
                        getRentalsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
                    ));
                    let foundRentalsByTitle = await Promise.all(titleSplited.map((value) =>
                        getRentalsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
                    ));
                    searchResults.rentals = searchResults.rentals.concat(foundRentalsByTitle);
                    searchResults.programs = searchResults.programs.concat(foundProgramsByTitle);
                }                    

             // Filter results code ...
             // .........................
             // End of Function               
        }

Any ideas on how can I refactor this into a nicer version? 关于如何将其重构为更好版本的任何想法?

Can be something like this: 可以是这样的:

if(!queryObj.title) return; // just exit from the function or return representation of an empty result


queryObj.title = queryObj.title.trim();
const titleSplited = queryObj.title.split(' ');//transform it to an array

if(titleSplited.length <= 0) return; // same as above

// define the holder for search operations
const searchPromises = {};

if(!queryObj.selectedSearchObjectType || queryObj.selectedSearchObjectType.indexOf("rentals") > -1)
{
  searchPromises.rentals = Promise.all(titleSplited.map((value) =>
    getRentalsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
  ));
}

if(!queryObj.selectedSearchObjectType || queryObj.selectedSearchObjectType.indexOf("programs") > -1)
{
  searchPromises.programs = Promise.all(titleSplited.map((value) =>
    getProgramsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
  ));
}

if (searchPromises.rentals) {
  searchResults.rentals = searchResults.rentals.concat(await searchPromises.rentals);
}

if (searchPromises.programs) {
  searchResults.programs = searchResults.programs.concat(await searchPromises.programs);
}

// Filter results code ...
// .........................
// End of Function

Later we can define type of searches and also extract search functions: 稍后,我们可以定义搜索类型并提取搜索功能:

const RENTALS = 'rentals';
const PROGRAMS = 'programs';

const searchFns = {
  [RENTALS]: (value) => getRentalsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } ),
  [PROGRAMS]: (value) => getProgramsByQuery({title: { $regex: new RegExp('\\b' + value.toLowerCase() + '\\b', 'i') } } )
};

So you can change your function to: 因此,您可以将功能更改为:

if(!queryObj.title) return; // just exit from the function or return representation of an empty result

queryObj.title = queryObj.title.trim();
const titleSplited = queryObj.title.split(' ');//transform it to an array

if(titleSplited.length <= 0) return; // same as above

// define the holder for search operations
const searchPromises = {};
const searchTypes = [RENTALS, PROGRAMS];

searchTypes.forEach((type) => {
  if(!queryObj.selectedSearchObjectType || queryObj.selectedSearchObjectType.indexOf(type) > -1)
  {
    searchPromises[type] = Promise.all(titleSplited.map(searchFns[type]));
  }
});

// iterate over created promises
for (let type in searchPromises) {
  searchResults[type] = searchResults[type].concat(await searchPromises[type])
}

// Filter results code ...
// .........................
// End of Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM