Я работаю над веб-приложением MEAN STACK, и в nodejs я хочу использовать асинхронное ожидание с блоком try catch. В следующем примере я хочу сделать код прямым вместо использования вложенных множественных попыток и уловов. Здесь мне нужно передать различные типы пользовательских ошибок во внешний интерфейс, если возникнет какая-либо ошибка.
БЫВШИЙ :
public async create(req: Request, res: Response) {
...
...
...
try {
...
...
...
let userResult = await userModel.addBasickInfo(userData);
...
...
...
try {
...
...
...
let userAddressResult = await userProfileModel.addAddress(addressData);
...
...
...
try {
...
...
...
let userProfileResult = await userAddressModel.addProfile(profileData);
...
...
...
return (<any>res).sendResponse(data, 'Information saved successfully');
} catch (err) {
return (<any>res).sendError(err.error ? err : new ErrorException('BadRequestError', "Error while adding user profile information"));
}
} catch (err) {
return (<any>res).sendError(new ErrorException('BadRequestError', 'Error while adding user address'));
}
} catch (err) {
return (<any>res).sendError(err.error ? err : new ErrorException('BadRequestError', 'Error while adding user information'));
}
}
Пожалуйста, помогите мне улучшить этот код.
Нужно ли делать это один за другим? Поскольку результат вашего первого вызова не используется во втором вызове, вы также можете использовать их независимо параллельно.
@Harshal: Да, это необходимо делать один за другим, потому что идентификатор пользователя хранится в userAddressModel и userProfileModel. и идентификатор адреса пользователя, хранящийся в модели профиля пользователя
Вы можете попробовать этот шаблон вместо вложения блока try-catch.
public async create(req: Request, res: Response) {
try {
let userResult = await userModel.addBasickInfo(userData);
} catch (err) {
return (<any>res).sendError(err.error ? err : new ErrorException('BadRequestError', 'Error while adding user information'));
}
try {
let userAddressResult = await userProfileModel.addAddress(addressData);
} catch (err) {
return (<any>res).sendError(new ErrorException('BadRequestError', 'Error while adding user address'));
}
try {
let userProfileResult = await userAddressModel.addProfile(profileData);
return (<any>res).sendResponse(data, 'Information saved successfully');
} catch (err) {
return (<any>res).sendError(err.error ? err : new ErrorException('BadRequestError', "Error while adding user profile information"));
}
}
Вам нужно будет обернуть асинхронный код небольшой вспомогательной функцией. Эта функция отформатирует разрешающие и отклоняющие аргументы в виде массива из двух элементов.
/**
* @param { Promise } promise
* @param { Object } improved - If you need to enhance the error.
* @return { Promise }
*/
export function utility(promise, improved){
return promise
.then((data) => [null, data])
.catch((err) => {
if (improved) {
Object.assign(err, improved);
}
return [err]; // which is same as [err, undefined];
});
}
Эта функция возвращает массив из двух элементов:
При обратном вызове then (если обещание разрешено): он возвращает значение null и данные, так как нет ошибок.
При обратном вызове catch (если обещание отклонено): возвращается ошибка который может быть расширен и не определен как второй элемент, поскольку есть нет данных.
Теперь вы можете взять исходный блок try/catch и обновить его таким образом. Здесь мы просто оборачиваем обещание someAsyncData нашей функцией utility
.
const [error, result] = await utility(someAsyncData());
if (error){
// log something and return ?
}
const [error2, result2] = await utility(someAsyncData2());
if (error2){
// do something else
} else {
// Here we are sure that result2 is defined and a valid value
}
Зачем нужна вложенность? Почему бы и нет
try { // addBasickInfo } catch {}; try { // addAddress } catch {}