2017-06-29 101 views
0

我很难理解处理错误的最佳方法。 下面的代码是一个很好的做法吗?这是承诺中错误处理的正确用法吗?

有更好,更短,更容易阅读的方式来处理流量和错误?

如何编写代码来处理所有错误,以免被吞下?谢谢。

privateProperties.setSearchedData = function (data, searchFor) { 
    return new Promise(function (resolve, reject) { 
     switch (searchFor) { 
     case "photos": 
      try { 
      var photoItems = []; 

      if (data.items && data.items.constructor === Array) { 
       data.items.forEach(function (value) { 
       if (value.link) { 
        photoItems.push(value.link); 
       } else { 
        console.error('Link is undefined'); 
        reject(new Error('Link is undefined')); 
       } 
       }); 
       privateProperties._uiInstances['main'].uiReference.set("photos.photoItems",photoItems) 
       .then(resolve(photoItems)) 
       .catch(function (error) { 
        reject(error); 
       }) 
      } else { 
       reject(new Error('Data.items is undefined or not array')); 
      } 
      } catch (e) { 
      throw e; 
      } 
     break; 

     case "videos": 
     break 
     } 
    }); 

    }; 
+0

这里的哪个调用是异步的?它是否是'uiReference.set'?你在回复什么? –

+0

是uiReference.set是异步的 – Mihai

+0

否。避免['Promise' constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-要避免的,它)!事实上,你在这里似乎并不需要承诺。 – Bergi

回答

1

如果我正确理解你的代码,你可以这样写:

privateProperties.setSearchedData = function(data, searchFor) { 
    switch (searchFor) { 

    case "photos": 
     if (!Array.isArray(data.items)) 
     return Promise.reject("data.items is undefined or not an array"); 

     const photoItems = data.items.map(item => item.link); 

     if (photoItems.some(item => !item)) { 
     console.error('Link is undefined'); 
     return Promise.reject("Link is undefined"); 
    } 

     return privateProperties._uiInstances['main'].uiReference 
     .set("photos.photoItems", photoItems); 

    case "videos": 
     return Promise.reject("videos not supported"); 
    } 
} 

你基本上是试图返回uiReference.set承诺,所以才返回。没有必要对其进行拒绝 - 拒绝将通过消费者处理。没有必要创建自己的承诺,然后根据其结果辛勤地做出您自己的新承诺resolvereject。只需返回你想要的承诺。错误检查可以在前面完成,并在这种情况下返回一个明确的拒绝承诺。

使用await,这可能如下所示。您可以throw而不是返回Promise.rejectthrow将导致函数返回被拒绝的承诺,并将其作为原因。

privateProperties.setSearchedData = async function(data, searchFor) { 
    switch (searchFor) { 
    case "photos": 
     return privateProperties._uiInstances['main'].uiReference 
     .set("photos.photoItems", data.items.map(item => item.link)); 

    case "videos": 
     throw new Error("videos not supported"); 
    } 
} 

我省略了一个数组的检查,因为非数组将使.map失败,这将导致返回拒绝出于某种原因,如“无法读取属性map一个承诺全功能的空“。

我也假设重新设计uiReference.set来检查丢失或空链接,并拒绝发生,所以我们不必检查链接是否都在那里。当所有事情都说完之后,这个功能真的只需要打开searchFor,从数据项中提取链接,然后调用并返回uiReference.set。就个人而言,我宁愿搜索照片和视频独立的功能,在这种情况下,它变得非常干净:

privateProperties.setSearchedPhotosData = async function(data) { 
    return privateProperties._uiInstances['main'].uiReference 
    .set("photos.photoItems", data.items.map(item => item.link)); 
} 

唯一剩下的async的目的是将的map失败(当data.items不是阵列)变成被拒绝的承诺。但是,如果这种情况代表编码错误,而不是您想要处理的半预期情况,则最好让它抛出(通过删除async)。

+0

s/can/should/:-) – Bergi

0

不,它不是。 ;)拒绝使用不new Error当你赶上一个错误不要使用throwreject(e)

那么以后你可以说

privateProperties.setSearchedData(...) 
    .then(callback) 
    .catch(errorCallback); 

旁注:分割你的代码转化为更多的功能更好的可读性。我猜想case "photos":(除了break)都可以是它自己的功能。

0
  1. 你抓住所有的错误,但只是扔掉它们。这完全等于只是不抓住他们。使用reject而不是throw

  2. 关于使用Promise更容易和更易读的方法,您可以使用async await,它使您的代码更具可读性和简洁性,并使用Promises。然后你的函数看起来像:

    privateProperties.setSearchedData =异步功能(数据,searchFor){

    switch (searchFor) { 
        case "photos": 
         var photoItems = []; 
    
         if (data.items && data.items.constructor === Array) { 
          data.items.forEach(function (value) { 
           if (value.link) { 
            photoItems.push(value.link); 
           } else { 
            console.error('Link is undefined'); 
            throw new Error('Link is undefined'); 
           } 
          }); 
          privateProperties._uiInstances['main'].uiReference.set("photos.photoItems",photoItems); 
          return photoItems; 
         } else { 
          throw new Error('Data.items is undefined or not array'); 
         } 
         break; 
    
        case "videos": 
         break 
    } 
    

    };

+0

您发布的代码段似乎没有使用async/await? – Bergi

+0

@Bergi我已经更新了它。 – Alon