【问题标题】:Rejecting Javascript Promises that are yet the be waited/THENed for拒绝等待/THENed 的 Javascript Promise
【发布时间】:2021-09-23 22:50:04
【问题描述】:

编辑:请参阅下面的编辑开始,

当我尝试拒绝承诺时收到此错误:-

“VM168:3 Uncaught(承诺)我爱你!!”

如果您查看下面的示例,您会发现 THEN 同时满足 Resolve 和 Reject 结果。如果您删除注释标记 /* */ 并再次运行它,您将看到没有生成错误。

为什么会出现这个错误?

w3schools 的示例学分:-

<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Promise</h2>

<p>Wait 3 seconds (3000 milliseconds) for this page to change.</p>

<h1 id="demo"></h1>

<script>
const myPromise = new Promise(function(myResolve, myReject) {
  setTimeout(function(){ myReject("I love You !!"); }, 3000);
});
/*
myPromise.then(function(value) {
  document.getElementById("demo").innerHTML = value;
},
function(value) {
  document.getElementById("demo").innerHTML = "Boom"+value;
});*/
</script>
<input typt="text"/>
</body>
</html>

编辑-开始

因此“未捕获(承诺中)”在控制台中显示为错误而不是警告,但所有后续指令(调用 myReject 后)都已执行。可能因为 IIRC,promise 被设计保留到下一个事件循环。

所以即使我尝试(看看我在那里做了什么 :-) 来捕获错误,我也做不到!

const myPromise = new Promise(function(myResolve, myReject) {
  setTimeout(
    function(){ try{
                    myReject("I love You !!");
                } catch(err) {
                  console.log("Err = "+err.message) 
                }
              }, 3000);
});

惊人的一致性和可追溯性:-(

至少 myPromise 的状态设置为 Rejected。感谢上天的小小怜悯!

【问题讨论】:

  • Why is this error occuring? 因为你有一个 Promise 拒绝,并且没有处理拒绝的代码
  • 承诺拒绝与抛出的异常非常相似,因此这类似于您在没有 try/catch 的情况下执行 throw "I love You !!"; 来处理异常(因此会在控制台中记录错误,例如这)。我个人会考虑使用任何不是instanceof Error 的值调用reject,这会引起我的担忧。
  • 这个错误总是发生,不管你处理与否。
  • Promises 和 aysync 编码的全部意义在于你可以在未来的任何时候等待/然后一个承诺,或者根本不?那么 REJECT 失败了吗?拒绝“失败”后 myPromise 的状态是什么。恕我直言,Promise longevity 和 Promise-State longevity 不应受到直接范围的限制。就我而言,我相信还有很多其他人,我还没有准备好等待承诺解决/拒绝。这是拒绝/状态更改,而不是抛出。
  • 您的问题是关于记录的时间吗,因为稍后可能会出现并执行myPromise.catch(err =&gt; {}),因此实际上最终可能会处理错误?如果是这样,那就很不清楚了。

标签: javascript ecmascript-6 promise es6-promise


【解决方案1】:

对于那些了解明显要求并且不希望您的控制台因虚假错误而搞砸的人,请在实例化您的 Promise 之后再退出范围(yield 事件线程):-

myPromise.then(()=>{},()=>{console.log("disbelief")});

尽管有异步功能!

完整示例:-

<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Promise</h2>

<p>Wait 3 seconds (3000 milliseconds) for this page to change.</p>

<h1 id="demo"></h1>

<script>
const myPromise = new Promise(function(myResolve, myReject) {
  setTimeout(
    function(){ try{
                    myReject("I love You !!");
                } catch(err) {
                  console.log("Err = "+err.message) 
                }
                setTimeout(stillThere,0);
              }, 3000);
});
myPromise.then(()=>{},()=>{console.log("disbelief")});
function stillThere() {
  console.log("start");
  myPromise.then(function(value) {
    document.getElementById("demo").innerHTML = value;
  },
  function(value) {
    document.getElementById("demo").innerHTML = "Boom"+value;
  });
  console.log("end");
}

</script>
<input typt="text"/>
</body>
</html>

【讨论】:

  • 尽量不要使用.then()的第二个参数。如果可能的话,更喜欢使用.catch()。所以总是像这样处理你的承诺:mypromise.then(handleIt).catch(console.log)
  • 另外,disbelief 不是一个有用的错误消息,你会在控制台中调试你的代码,查看大量的disbelief。只需将 console.log 传递给您的 promise 的 .catch() 方法即可。
  • @slebetman absolutely nothing wrong with using the second argument to then 是有意义的。当然,不传递任何内容作为第一个参数意味着您应该简化为 .catch(…)
  • @Bergi 我发现它的可读性较差,因为您不会立即看到代码的意图。使用.catch(),它会告诉您它正在捕获错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-04
  • 2020-12-19
相关资源
最近更新 更多