代码之家  ›  专栏  ›  技术社区  ›  Marcus Junius Brutus

未发现(承诺中)错误

  •  1
  • Marcus Junius Brutus  · 技术社区  · 7 年前

    这显然是一个SSCC。我有以下(J小提琴 here ):

    <html>
      <body>
        <input id='file-dlg' type='file'/>
        <br/>
        <button id='submit' type='button'>submit</button>
        <script>
         document.getElementById('file-dlg').addEventListener('change', storeAPromise);
         var p; 
         function storeAPromise() {
           p = new Promise(function executor(resolve, reject) {
             try {
               throw new Error('snafu');
             } catch(e) {
               reject(e);
             }
           });
         };
         document.getElementById('submit').onclick = function() {
           p.then(function() {}, function reject(e) {
             console.error('some problem happenned', e);
           });
         };
        </script>
      </body>
    </html>
    

    当用户使用“文件”对话框选择文件时,我希望控制台上没有任何内容作为 Error 被抓住了承诺 reject 调用函数。相反,我希望只有在单击“提交”按钮时,错误才会出现在控制台上,并带有“发生了一些错误”的描述。

    然而,这不是我所观察到的。一旦用户使用控制台上的对话框选择一个文件:

    Uncaught (in promise) Error: snafu(…)
    

    当用户按下“提交”按钮时,我确实看到了预期的日志行“发生了一些问题”,但我不理解为什么当用户使用文件对话框选择文件时,我也看到了早期的“未捕获(承诺)”日志行。我也不明白为什么错误被描述为“未捕获”,因为我捕获(无条件)所有异常并简单地调用 拒绝 功能。

    1 回复  |  直到 7 年前
        1
  •  6
  •   Bergi    7 年前

    这不是一个不受重视的 例外 ,这是一个不可忽视的 拒绝 . 承诺不应该在拒绝状态下悬空而不附加错误回调——这就是控制台警告您这一点的原因。您还可以在应用程序中使用 unhandledrejection event .

    如果以后要处理该错误(当用户单击按钮时安装该处理程序,可能永远不会!),您仍然需要立即安装一个空回调(显式忽略错误),以取消警告。

    var p = Promise.resolve();
    document.getElementById('file-dlg').addEventListener('change', function createPromise() {
      p = new Promise(function executor(resolve, reject) {
        throw new Error('snafu');
      });
      p.catch(e => {/* ignore for now */});
    });
    document.getElementById('submit').addEventListener('click', function addErrorHandler() {
      p.catch(function onReject(e) {
        console.error('some problem happened', e);
      });
    });
    

    注意你不需要那个 try / catch -在默认情况下,Promise构造函数将捕获执行器的所有异常。

    推荐文章