栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Javascript承诺模式-区分错误

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Javascript承诺模式-区分错误

我认为解决了以下问题的以下模式是否被视为无极反模式?

不,还好。

有更好的方法吗?

是的,看看和之间

.then(…).catch(…)``.then(…,…)
。如果要严格区分成功案例(继续)和错误案例(报告此特定问题),则将两个回调传递给
then
是一个更好的主意。这样,外部处理程序将不会由于成功案例代码中的失败而被触发,而只能由安装它的Promise中的失败触发。在您的情况下:

getUser(userId).then(function(user) {    return chargeCreditCard(user)    .then(function(chargeId) {        return saveChargeId(chargeId)        .then(function(chargeHistoryId) { return associateChargeToUsers(chargeHistoryId); .then(function(result) {     return finalFormatting(result); }, function(error){     crashreporter.reportError('chargeHistoryId DB failed', error);     return 3; });        }, function(error){ crashreporter.reportError('ChargeId DB failed', error); return 2;        });    }, function(error){        crashreporter.reportError('Credit card failed', error);        return 4;    });}, function(error){    crashreporter.reportError('User DB failed', error);    return 1;}).then(showToUser);

尽管您可能想使用通用错误处理程序:

getUser(userId).catch(function(error){    crashreporter.reportError('User DB failed', error);    throw new Error(1);}).then(function(user) {    return chargeCreditCard(user)    .catch(function(error){        crashreporter.reportError('Credit card failed', error);        throw new Error(4);    });}).then(function(chargeId) {    return saveChargeId(chargeId);    .catch(function(error){        crashreporter.reportError('ChargeId DB failed', error);        throw new Error(2);    });}).then(function(chargeHistoryId) {    return associateChargeToUsers(chargeHistoryId);    .catch(function(error){        crashreporter.reportError('chargeHistoryId DB failed', error);        throw new Error(3);    });}).then(function(result) {    return finalFormatting(result);}, function(error) {    return error.message;}).then(showToUser);

在这里,每个

then
回调都会返回一个承诺,该承诺会自行拒绝并产生相应的错误。理想情况下,每个被调用的函数都已经做到了,当它们没有这样做时,您需要
catch
向每个函数附加一个特定的参数,您可能想使用包装器辅助函数(可能是
crashreporter
?的一部分)。

function withCrashReporting(fn, msg, n) {    return function(x) {        return fn(x)        .catch(function(error){ crashreporter.reportError(msg, error); throw new Error(n);        });    };}withCrashReporting(getUser, 'User DB failed', 1)(userId).then(withCrashReporting(chargeCreditCard, 'Credit card failed', 4)).then(withCrashReporting(saveChargeId, 'ChargeId DB failed', 2)).then(withCrashReporting(associateChargeToUsers, 'chargeHistoryId DB failed', 3)).then(finalFormatting, function(error) {    return error.message;}).then(showToUser);

我看到的问题是,您可能会陷入半回调地狱。

不,这只是包装的适当水平。与回调地狱相反,它可以展平为最大嵌套数为2,并且始终具有返回值。

如果您绝对想避免嵌套和回调,请使用

async
/
await
,尽管实际上更加难看:

try {    var user = await getUser(userId);} catch(error) {    crashreporter.reportError('User DB failed', error);    return showToUser(1);}try {    var chargeId = chargeCreditCard(user);} catch(error) {    crashreporter.reportError('Credit card failed', error);    return showToUser(4);}try {    var chargeHistoryId = saveChargeId(chargeId);} catch(error) {    crashreporter.reportError('ChargeId DB failed', error);    return showToUser(2);}try {    var result = associateChargeToUsers(chargeHistoryId);} catch(error) {    crashreporter.reportError('chargeHistoryId DB failed', error);    return showToUser(3);}return showToUser(finalFormatting(result));


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/436622.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号