【问题标题】:Unexpected literal in error position of callback in Vue.JSVue.JS 中回调错误位置的意外文字
【发布时间】:2026-01-19 17:55:01
【问题描述】:

我正在尝试学习本教程:https://developer.okta.com/blog/2017/09/14/lazy-developers-guide-to-auth-with-vue

但是得到:

 ERROR  Failed to compile with 1 errors    
 error  in ./src/auth.js

  ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:7:15
        if (cb) cb(true)
                 ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:14:17
          if (cb) cb(true)
                   ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:17:17
          if (cb) cb(false)
                   ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:43:7
        cb({
         ^
      ✘  https://google.com/#q=standard%2Fno-callback-literal  Unexpected literal in error position of callback
  src/auth.js:48:7
        cb({ authenticated: false })
         ^
✘ 5 problems (5 errors, 0 warnings)

Errors:
  5  https://google.com/#q=standard%2Fno-callback-literal

 @ ./src/router/index.js 3:0-26
 @ ./src/main.js
 @ multi ./build/dev-client ./src/main.js

> Listening at http://localhost:8080

失败的代码如下:

/* globals localStorage */

export default {
  login (email, pass, cb) {
    cb = arguments[arguments.length - 1]
    if (localStorage.token) {
      if (cb) cb(true)
      this.onChange(true)
      return
    }
    pretendRequest(email, pass, (res) => {
      if (res.authenticated) {
        localStorage.token = res.token
        if (cb) cb(true)
        this.onChange(true)
      } else {
        if (cb) cb(false)
        this.onChange(false)
      }
    })
  },

  getToken () {
    return localStorage.token
  },

  logout (cb) {
    delete localStorage.token
    if (cb) cb()
    this.onChange(false)
  },

  loggedIn () {
    return !!localStorage.token
  },

  onChange () {}
}

function pretendRequest (email, pass, cb) {
  setTimeout(() => {
    if (email === 'joe@example.com' && pass === 'password1') {
      cb({
        authenticated: true,
        token: Math.random().toString(36).substring(7)
      })
    } else {
      cb({ authenticated: false })
    }
  }, 0)
}

所以一般来说它是if (cb) cb(X)

尝试谷歌这些东西似乎 cb(false)cb(true) 是不允许的,但我被困在如何通过这个例子轻松解决它。

这是我的登录代码:

  import auth from '../auth'
  export default {
    data () {
      return {
        email: 'joe@example.com',
        pass: '',
        error: false
      }
    },
    methods: {
      login () {
        auth.login(this.email, this.pass, loggedIn => {
          if (!loggedIn) {
            this.error = true
          } else {
            this.$router.replace(this.$route.query.redirect || '/')
          }
        })
      }
    }
  }

【问题讨论】:

  • 你没有在第二个作用域中定义cb,preseptRequest没有cb参数
  • @afcosta fakeRequest 在登录范围内。
  • 这些错误来自哪里?你在用一些 linter 吗?
  • 我正在使用 ESLint,正如教程中所建议的那样 - 所以这可能是一个原因?
  • 并且 ESLint 预设为“标准”。

标签: javascript node.js vue.js eslint


【解决方案1】:

这似乎是由您使用的某些代码 linting 工具引起的。它认为您需要将错误作为回调的第一个参数传递。您可以通过将函数名称从 cb 更改为 cb 或回调以外的其他名称来解决此问题。

这是您首先使用登录回调时出错的方式:

auth.login(this.email, this.pass, (err, loggedIn) => {
  if (err) {
    // Probably do something with the error
    // LoggedIn isn't really necessary, unless it contains some info about the logged in user
    this.error = true
  } else {
    this.$router.replace(this.$route.query.redirect || '/')
  }
})

【讨论】:

  • 如果我想先调用 cb 并出现错误怎么办,你能举个例子 - 这样我可以调整代码吗?
  • 您的问题中没有调用login 的代码,但您只需修改该回调函数以将错误作为第一个参数。然后在您的登录功能中,您将调用 cb(error, value) 而不是 cb(value)
  • 刚刚添加了login电话。
  • @AlfredBalle 编辑了答案
【解决方案2】:

ESLint 批准no-callback-literal 规则后的这个问题。

但是有 many many 抱怨它。我看到它在不久的将来会被删除或至少修改。

目前它与 Express.JS 中处理错误的方式相匹配。实际上它不正确地匹配:

callback({foo: 'bar'})

同时,您可以通过更改 .eslintrc.js 来禁用它,使规则如下所示:

'rules': {
  ...
  'standard/no-callback-literal': 0,
  ...
}

【讨论】:

    【解决方案3】:

    根据标准 JS,不允许在回调文字中进行 linting。所以 callback({foo: 'bar'}) 可以写成如下:

    let somedata = {foo: 'bar'}    
    callback(somedata)
    

    所以cb({ authenticated: false }) 这可以相应地格式化。

    【讨论】: