完成后逃离承诺链[重复]
Posted
技术标签:
【中文标题】完成后逃离承诺链[重复]【英文标题】:Escaping the promise chain when it's completed [duplicate] 【发布时间】:2018-10-22 10:02:48 【问题描述】:我想在启动我的应用程序之前使用 Promise 链加载一些数据。所以,我会有类似的东西:
fetch('path/to/data.json')
.then((response) => response.json())
.then((data) =>
console.log(`Hey cool, we're done w/ the promise chain here`);
startApp(data);
)
.catch((error) => console.error(`Error in promise chain: $error`));
它确实有效——但使用此设置,我的 startApp
函数(或任何后续函数)中的任何错误都会在 Promise 链中得到处理,这似乎是错误的。
我发现的 Promise 示例通常以链的最后一个 then()
中的控制台日志结尾,因此它们对此没有太大的指导意义。
startApp
函数而不仍然在链中?
【问题讨论】:
这很好.....finally()
也是一个选项
好的,好的,谢谢@DanielA.White
如果你的startApp
也是一个promise,请注意错误会丢失而不会被捕获。
【参考方案1】:
您将永远处于承诺链中。但是,您可以轻松地将处理fetch
错误的逻辑与您的数据消耗应用程序分开,如下所示:
fetch('path/to/data.json')
.then(response => response.json())
.then(startApp, handleFetchError)
.catch(error => console.error(`Error from startApp or handleFetchError: $error`));
【讨论】:
【参考方案2】:根据问题中观察到的效果,Promise 实现在 try/catch
块内调用 .then
处理程序。如果捕获到错误,then
返回的 Promise 会以同样的原因被拒绝。
要单独报告应用程序错误,您可以在应用程序周围放置自己的 try/catch
块并明确处理错误报告。如果***then
处理程序返回而没有重新抛出错误,则不会调用以下catch
处理程序。
例如
fetch('path/to/data.json')
.then((response) => response.json())
.then((data) =>
console.log(`Hey cool, we're done w/ the promise chain here`);
try
startApp(data);
catch( err)
console.log( "An application error occurred:");
console.error( err);
// returning without re-throwing the error
)
.catch((error) => console.error(`Error in promise chain: $error`));
我还看到用于在承诺链之外抛出错误的计时器调用,以防止它们被作为承诺错误消耗。不确定堆栈跟踪是否足够,但至少它可以确定发生了应用程序错误:
例如
fetch('path/to/data.json')
.then((response) => response.json())
.then((data) =>
console.log(`Hey cool, we're done w/ the promise chain here`);
try
startApp(data);
catch( err)
setTimeout( function () throw err, 0);
)
.catch((error) => console.error(`Error in promise chain: $error`));
另一种方法是使用计时器启动应用程序,这样它就不会在承诺链中执行以启动:-)
setTimeout(startApp, 0, data);
【讨论】:
我对专门捕捉错误不太感兴趣,只是那种我认为应该在仍然存在于其中的承诺链之后出现的“错误”感觉。它有一种在大量代码周围放置 try/catch 的感觉。 setTimeout 实际上完成了这项工作,跳过了调用堆栈——但出于某种原因,感觉 more 错了哈哈setTimeout
可以满足目的。注意 setTimout
不会“跳过调用堆栈”,因为承诺和计时器回调都使用新堆栈执行。最大的区别在于,promise 回调的执行由 then/catch 调用返回的 promise 的 executor 函数监控,以查看如果处理程序抛出错误,promise 是否应该被拒绝 - 而计时器回调只是报告未捕获的错误控制台作为“未捕获的异常”。以上是关于完成后逃离承诺链[重复]的主要内容,如果未能解决你的问题,请参考以下文章