【问题标题】:Throw an error if undefined?如果未定义抛出错误?
【发布时间】:2018-11-15 02:59:49
【问题描述】:

如果无法从data 找到属性,有没有办法抛出错误。

问题是,它映射undefined 而不是抛出错误。

const insertIntoTable = function(data) {
    return new Promise((resolve, reject) => {
        const entry = {
            Id: data.id,
            Method: data.Method,
            Status: data.PaymentStatus,
            InsertedAt: (new Date().getTime())
        }
    }).catch((error) => {
       console.log(error); 
    });
}

【问题讨论】:

  • 你永远不会兑现你的承诺
  • 您必须手动检查每个属性,例如if (data.id === undefined) throw new Error("mapping undefined") 也调用resolve/reject 来解决promise。

标签: javascript node.js


【解决方案1】:

您可以通过将其与undefined 进行比较来检查属性是否未定义。例如,如果您想检查可以使用的 id 属性

 if(data.id === undefined){
     throw new Error();
}

【讨论】:

  • 如果我们使用 Promise,我们不应该抛出错误。
【解决方案2】:
const insertIntoTable = function(data) {
return new Promise((resolve, reject) => {
    if(data.id){
      const entry = {
        Id: data.id,
        Method: data.Method,
        Status: data.PaymentStatus,
        InsertedAt: (new Date().getTime())
      }
      return resolve(entry);
    }
    return reject();

    })
    .then((data) => {
        // treat your entry data
    }) 
    .catch(() => {
       throw new Error("data is undefined")
    });
}

【讨论】:

  • 不需要返回resolvereject,除了OP要检查个别属性,而不仅仅是data
  • 我回来只是为了不需要else。所以,改变你的条件,比如data.id !== undefined
  • 别的不用了,函数最后调用的是reject
  • 根据我对 Promise 的理解,您不会发帖返回 resolvereject。你打电话给他们就行了。为什么要退货?
  • @TruongDang 看来它确实改变了代码的工作方式。根据this post,返回会停止函数。没有它,该功能可以继续进行。有趣...
【解决方案3】:

一种方法是利用短路评估,并执行以下操作:

const insertIntoTable = function(data) {
  return new Promise((resolve, reject) => {
      const entry = {
        Id: data.id || reject("data.id is undefined"),
        Method: data.Method  || reject("data.Method is undefined"),
        Status: data.PaymentStatus  || reject("data.PaymentStatus is undefined"),
        InsertedAt: (new Date().getTime())
      }
      resolve(entry);
  }).catch((error) => {
    console.log(error);
  });
}

insertIntoTable({}).then(data => console.log(data));

但是,我觉得这很难阅读,所以我目前正在寻找更好的替代方案。

更新

我一直在使用提供可选或默认行为的代理来开发一个函数,该函数是

function optional(obj, evalFunc, def) {

  // Our proxy handler
  const handler = {
    // Intercept all property access
    get: function(target, prop, receiver) {
      const res = Reflect.get(...arguments);

      // If our response is an object then wrap it in a proxy else just return
      return typeof res === "object" ? proxify(res) : res != null ? res : def;
    }
  };

  const proxify = target => {
    return new Proxy(target, handler);
  };

  // Call function with our proxified object
  return evalFunc(proxify(obj, handler));
}

并且可以在这里应用

const insertIntoTable = function(data) {
  return new Promise((resolve, reject) => {
      const entry = {
        Id: optional(data, t => t.Id, reject('Id is not present')),
        Method: optional(data, t => t.Method, reject('Method is not present')),
        Status: optional(data, t => t.PaymentStatus, reject('PaymentStatus is not present')),
        InsertedAt: (new Date().getTime())
      }
      resolve(entry);
  }).catch((error) => {
    console.log(error);
  });
}

insertIntoTable({}).then(data => console.log(data));

这样做的好处是它支持深度属性访问。

【讨论】:

  • 不要使用 try-catch。只需使用 Promise 的 reject.catch 就像它是要使用的帖子一样。使用 if 条件来确定是否应该调用拒绝。
  • @J.Pichardo 创建一个执行未定义检查逻辑的新函数怎么样?
  • @user88432 这实际上是我的想法。我身边有一个,让我看看。
  • @user88432 不是,我删除了。
  • stackoverflow 从什么时候开始允许代码 sn-ps... 很酷
【解决方案4】:

首先你需要正确启动你的 Promise,因为你没有解决它,我喜欢这样做:

const insertIntoTable = function(data) {
    return Promise.resolve()
    .then(() => {
        const entry = {
            Id: data.id,
            Method: data.Method,
            Status: data.PaymentStatus,
            InsertedAt: (new Date().getTime())
        }
        // Do something with entry
    })
    .catch((error) => {
       console.log(error); 
    });
}

这样你就可以把验证扔进去(而不是拒绝)

您可以创建一个检查未定义的验证函数,如下所示:

const validate = property => {
    if (property === undefined) throw 'data missing required property'
    return property
}

然后像这样使用它:

const entry = {
    Id: validate(data.id),
    Method: validate(data.Method),
    Status: validate(data.PaymentStatus),
    InsertedAt: (new Date().getTime())
}

但是这样你总是会得到同样的错误。您可以更改它以根据属性名称显示错误:

const getAndValidate = (data, propertyName) => {
    const property = data[propertyName]
    if (property === undefined) throw 'data missing the required property' + propertyName
    return property 
}

然后像这样使用它:

const entry = {
    Id: getAndValidate(data, 'id'),
    Method: getAndValidate(data, 'Method'),
    Status: getAndValidate(data, 'PaymentStatus'),
    InsertedAt: (new Date().getTime())
}

这样你每次都会得到正确的错误,但我不喜欢使用字符串名称访问属性

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-30
    • 2014-07-09
    • 1970-01-01
    • 2018-01-08
    • 2019-04-19
    • 2016-12-14
    • 2016-02-11
    相关资源
    最近更新 更多