代码之家  ›  专栏  ›  技术社区  ›  Kenny83

用JavaScript实现具有承诺的快速失败设计

  •  1
  • Kenny83  · 技术社区  · 6 年前

    我不确定“fail fast”是否是描述这种方法的最佳方式,但自从我开始学习编程以来,我一直被教导如何设计这样的函数:

    function doSomething() {
        ... // do error-prone work here
    
        if (!allGood) {
            // Report error, cleanup and return immediately. Makes for cleaner,
            // clearer code where error-handling is easily seen at the top
            ...
            return;
        }
    
        // Success! Continue on with (potentially long and ugly) code that may distract from the error
    }
    

    doSomethingAsync(param).catch(err => {
        console.error(err);
    }).then(() => {
        // Continue on with the rest of the code
    });
    

    但这让我的行为类似于 finally 经典之作 try...catch...finally 声明,即 then() 阻止遗嘱 即使在出错后也会被调用。有时这很有用,但我很少发现自己需要这样的功能(或者 try...catch

    因此,为了尽可能快而清楚地失败,有没有一种方法可以让上面的第二个例子以我期望的方式工作(即。 仅在以下情况下执行 catch() 还不是单身 仍将捕获由引发的所有错误 doSomethingAsync() )?

    1 回复  |  直到 6 年前
        1
  •  1
  •   CertainPerformance    6 年前

    如果你使用 async await 而不是 .then ,您可以有效地等待承诺解决(或拒绝),如果它拒绝,请提前返回:

    (async () => {
      try {
        await doSomethingAsync(param);
      } catch(err) {
        console.error(err);
        return;
      }
      // Continue on with the rest of the code
    })();
    

    const doSomethingAsync = () => new Promise((resolve, reject) => Math.random() < 0.5 ? resolve() : reject('bad'));
    
    (async () => {
      try {
        await doSomethingAsync();
      } catch(err) {
        console.error(err);
        return;
      }
      console.log('continuing');
    })();

    .then(onResolve, onReject) 技术,虽然是 usually not recommended :

    function onReject(err) {
      console.log(err);
    };
    doSomethingAsync(param).then(onResolve, onReject);
    function onResolve() {
      // Continue on with the rest of the code
    }
    

    const doSomethingAsync = () => new Promise((resolve, reject) => Math.random() < 0.5 ? resolve() : reject('bad'));
    
    function onReject(err) {
      console.log(err);
    };
    doSomethingAsync().then(onResolve, onReject);
    function onResolve() {
      console.log('continuing');
    }

    这将有 onReject 只有 处理由引发的错误 doSomethingAsync(param) onResolve 也可以扔进它的身体里,那你就得把另一个链子拴起来 .catch 在它上面(这将开始看起来有点混乱-只在一个地方发现错误通常更好)

    推荐文章