【问题标题】:I can't make my Promise to properly reject with a new Error message, caught from a try/catch我无法让我的 Promise 正确拒绝一个新的错误消息,从 try/catch 中捕获
【发布时间】:2017-07-18 20:24:36
【问题描述】:

我有一个 Promise 方法来解析来自网络的链接。它返回一个我尝试从中访问link 键的对象,但是当这个对象为空时,它会以某种方式跳过if 我必须检查它的长度,从而导致一个可耻的错误。在代码下方。

首先,解析链接的Promise方法:

* parseReporter() {
  const article = new Promise((resolve, reject) => {
    parser.parseURL(`https://www.google.com/alerts/feeds/${this.googleAlertsUrlId}/${this.reporterUrlId}`, (err, parsed) => {
      if (err) {
        reject(new Error(err))
      }

      if (parsed.feed.entries.length === 0) {
        reject(new Error('Nothing to parse'))
      }

      const link = parsed.feed.entries[0].link
      const betterLink = link.substring(42, link.indexOf('&ct='))

      mercury.parse(betterLink).then((data) => {
        resolve(data)
      }).catch((err) => {
        reject(new Error(err))
      })
    })
  })

  return article
}

然后,这里是调用这个parseReporter()的方法:

* _getLastestNews(userReporter) {
  const reportersOperation = new ReportersOperation()

  reportersOperation.googleAlertsUrlId = userReporter.url.split('/')[3]
  reportersOperation.reporterUrlId = userReporter.url.split('/')[4]

  try {
    return yield reportersOperation.parseReporter()
  } catch (e) {
    this.addError(HTTPResponse.STATUS_INTERNAL_SERVER_ERROR, e.message)

    return false
  }
}

当它尝试从parsed.feed.entries[0] 访问link 时导致该错误。我已经注销了length,我确认要工作并显示一个号码,但它坚持跳过它。我对 Promise it try/catch 自己做错了吗?

【问题讨论】:

  • 我建议对reject 的前两个调用应该是return reject - 因为拒绝不会“停止”其余代码的运行......因此,@987654332 的拒绝@ 被调用,但随后代码继续尝试使用 ...[0].link - 这会引发错误 - 它不会被 Promise 代码内部的奇迹“处理”
  • 你的意思是,在前两个if,到rejectparsed
  • no ... 我说把 return 这个词放在 reject 之前 - 这样它之后的代码就不会被执行 - 因为 reject 不从函数返回
  • 太棒了。有效。请写一个答案让我接受。

标签: javascript error-handling promise try-catch


【解决方案1】:

reject 不会从像 return 这样的函数“停止”或“返回”

因此,您的代码正在检查错误情况,但继续进行,就好像数据正常

通过在调用reject 之前添加return,您将阻止这种情况的发生

仅显示更改的代码区域:

      // snip
      if (err) {
        return reject(new Error(err))
      }

      if (parsed.feed.entries.length === 0) {
        return reject(new Error('Nothing to parse'))
      }

      const link = parsed.feed.entries[0].link
      const betterLink = link.substring(42, link.indexOf('&ct='))
      //snip

【讨论】:

    【解决方案2】:

    此外,Jaramonda 建议,当你有一个承诺并且你确实在两条路径中解决和拒绝时,你也在使用反模式。你可以更有效地做到这一点:

      resolve(mercury.parse(betterLink));
    

    但是,你真正应该做的是你应该承诺parser.parseURL(),这样你就可以使用承诺来编写所有的控制流逻辑。这更加万无一失,并创建了一个可重用的接口,该接口使用您可以在其他地方使用的 Promise:

    // make promisified version of parser.parseURL()
    parser.parseURLP = function (url) {
        return new Promise((resolve, reject) => {
            parser.parseURL(url, (err, parsed) => {
                if (err) return reject(new Error(err));
                resolve(parsed);
            });
        });
    };
    
    function parseReporter() {
        return parser.parseURL(`https://www.google.com/alerts/feeds/${this.googleAlertsUrlId}/${this.reporterUrlId}`).then(parsed => {
            if (parsed.feed.entries.length === 0) {
                throw new Error('Nothing to parse');
            }
    
            const link = parsed.feed.entries[0].link
            const betterLink = link.substring(42, link.indexOf('&ct='))
    
            return mercury.parse(betterLink).catch(err => {
                // wrap error in Error object
                throw new Error(err);
            })
        })
    }
    

    【讨论】:

    • 我在== 处收到错误消息ParseError: Unexpected Token
    • @GabrielMFernandes - 只是一个错字。应该是parser.parseURLP =
    • 仍然,第一个点被指责有错误,还有以下方法的左大括号,并且都缺少;。我正在使用 AdonisJS。
    • @GabrielMFernandes - 我必须查看您的实际代码才能知道它有什么问题。这听起来像是代码中的语法错误。如果这不是您可以弄清楚的,那么我只能在我能看到整个相关代码部分(包括错误位置之前和之后的内容)的情况下提供帮助。
    猜你喜欢
    • 2016-06-21
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-12
    • 2023-01-14
    • 2022-01-05
    • 2019-02-28
    • 2021-04-21
    相关资源
    最近更新 更多