JavaScript多个“尝试”

时间:2018-08-22 02:40:11

标签: javascript

我们都知道JS中的基本转义机制:

try {
    ...
}
catch(err) {
    ..
}

我有一个JSON数据,我想在其中检查销售线索是否具有全名。如果不是这样,请尝试使用名字和姓氏字段(实际上我也用硬编码在其中空格也是一个问题)组成一个字段,最后如果所有失败都显示“ No Name”。

或使用伪代码:

try {
    name = lead['Details']['Name']['Full'];
} else try {
    name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
} catch (e) {
    name = "No Name";
}

有什么建议吗?

3 个答案:

答案 0 :(得分:4)

您可以将第二个try / catch块嵌套在第一个try / catch块的异常块中,如下所示:

try {
    name = lead['Details']['Name']['Full'];
} catch(ex0) {      
  try {
      name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
  } catch (ex1) {
      name = "No Name";
  }
}

这是有效的语法,在功能上等同于您的要求

答案 1 :(得分:0)

除了2年后的事实,但即使在此前甚至还得到Babeljs的支持,最佳拟合解决方案都应该基于Optional chaining,这个Q仍然是实践完全基于功能的方法的理想目标。

实施例如afterThrowing method modifier可能会导致表达式与OP的伪代码一样短……

try {
  name = lead['Meta']['Name']['Full'];
} else try {
  name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
} catch (e) {
  name = 'No Name';
}

...然后会变成类似...

function getFullName(lead) {
  return lead['Meta']['Name']['Full'];
}
function getComposedFullName(lead) {
  return lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
}

const name = (getFullName.afterThrowing((error, [data] = args) =>

  (getComposedFullName.afterThrowing((/*error,[data]=args*/) => 'No Name')(data))

)(lead));

...实现和示例代码作为概念证明...

const leadTestSample = {
  success: {
    fullName: {
      Meta: {
        Name: {
          Full: "Mary Jane Doe"
        }
      }
    },
    composed: {
      Details: {
        Name: {
          First: "Jane",
          Last: "Doe"
        }
      }
    }
  },
  failure: {
    Meta: {},
    Details: {}
  }
};


function getFullName(lead) {
  return lead['Meta']['Name']['Full'];
}
function getComposedFullName(lead) {
  return lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
}
const nameDefault = 'No Name';


/*
try {
  name = lead['Meta']['Name']['Full'];
} else try {
  name = lead['Details']['Name']['First'] + " " + lead['Details']['Name']['Last'];
} catch (e) {
  name = 'No Name';
}
*/

const fullNameData = leadTestSample.success.fullName;
const composedData = leadTestSample.success.composed;
const failureData = leadTestSample.failure;

console.log(
  (getFullName.afterThrowing((error, [data] = args) =>

    (getComposedFullName.afterThrowing(() => nameDefault)(data))

  )(fullNameData))
);
console.log(
  (getFullName.afterThrowing((error, [data] = args) =>

    (getComposedFullName.afterThrowing(() => nameDefault)(data))

  )(composedData))
);
console.log(
  (getFullName.afterThrowing((error, [data] = args) =>

    (getComposedFullName.afterThrowing(() => nameDefault)(data))

  )(failureData))
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>
  (function (Function) {

    const fctPrototype = Function.prototype;
    const FUNCTION_TYPE = (typeof Function);

    function isFunction(type) {
      return (
           (typeof type == FUNCTION_TYPE)
        && (typeof type.call == FUNCTION_TYPE)
        && (typeof type.apply == FUNCTION_TYPE)
      );
    }
    function getSanitizedTarget(target) {
      return ((target != null) && target) || null;
    }

    function afterThrowing/*Modifier*/(handler, target) {
      target = getSanitizedTarget(target);

      const proceed = this;
      return (

        isFunction(handler) &&
        isFunction(proceed) &&

        function () {
          const context = target || getSanitizedTarget(this);
          const args = arguments;

          let result;
          try {
            result = proceed.apply(context, args);

          } catch (exception) {

            result = handler.call(context, exception, args);
          }
          return result;
        }

      ) || proceed;
    }
    // afterThrowing.toString = () => 'afterThrowing() { [native code] }';

    Object.defineProperty(fctPrototype, 'afterThrowing', {
      configurable: true,
      writable: true,
      value: afterThrowing/*Modifier*/
    });

  }(Function));
</script>

我不介意有一天JavaScript正式启用... Function.prototype[ before | after | around | afterThrowing | afterFinally ]

答案 2 :(得分:0)

而不是仅使用一个try-catch块来执行此操作。我们知道,访问不存在的内容时,会在javascript中出现类型错误。

请参见下面的代码段。

type="url"

如果全名未定义,那么我们需要添加一个额外的if块来检查未定义的大小写。