我很难理解处理错误的最佳方法。 下面的代码是一个好的做法吗?
是否有更好,更短,更易于阅读的方式来处理流量和错误?
您如何编码处理所有错误,以免被吞下?谢谢。
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 :(得分: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
承诺,所以请将其返回。没有必要catch
拒绝它 - 拒绝将被传递给消费者处理。没有必要创建自己的承诺,然后根据其结果费力resolve
或reject
您自己的新承诺。只需返回您想要的承诺。错误检查可以预先完成,并且在这种情况下会返回明确拒绝的承诺。
使用await
,可能如下所示。您可以throw
而不是返回Promise.reject
。 throw
将导致函数返回被拒绝的承诺,并将其作为理由。
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
失败,这将导致整个函数返回由于某些原因拒绝的承诺,例如&#34 ;无法读取null"的属性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
)。
答案 1 :(得分:0)
不,不是。 ;)使用不带new Error
的拒绝,当您发现错误时,请不要使用throw
,reject( e )
然后你可以说
privateProperties.setSearchedData( ... )
.then( callback )
.catch( errorCallback );
旁注:将代码拆分为更多功能,以提高可读性。我想case "photos":
内的所有内容(除了中断)都可以是它自己的函数。
答案 2 :(得分:0)
你捕获所有错误,但然后扔掉它们。它完全等于首先不抓住它们。使用reject
代替throw
。
关于使用Promises的更简单,更易读的方法,您可以使用async await使您的代码更具可读性和简洁性,并在引擎盖下使用Promise。然后你的功能将是这样的:
privateProperties.setSearchedData = async function(data,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
}
};