在另一个承诺中解决承诺

时间:2017-02-02 20:18:15

标签: javascript promise es6-promise vuejs2 vue-resource

我很擅长承诺并且在掌握如何将两个承诺结合在一起时遇到一些麻烦。我有一个功能可以解决一个承诺,并完成一些任务:

loginService (context, credentials) {
  context.$http.post(LOGIN_URL, credentials, { emulateJSON: true}).then(response => {
    this.user.authenticated = true
    localStorage.setItem(TOKEN_STORAGE_NAME, response.body[TOKEN_NAME])
  }).catch(response => {
    context.error = response.body
  })
},

我想修改上面的代码,以便我可以执行以下操作:

login () {
  this.submitButtonLoading = true
  loginService(this, this.credentials).then(response => {
    this.submitButtonLoading = false
    // Do something else here.
  }).catch(response => {
    this.submitButtonLoading = false
    // Do something else here.
  })
}

处理此问题的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

loginService返回承诺,然后您可以继续链接:

loginService (context, credentials) {
  return context.$http.post(LOGIN_URL, credentials, { emulateJSON: true})
    .then(response => {
      this.user.authenticated = true
      localStorage.setItem(TOKEN_STORAGE_NAME, response.body[TOKEN_NAME])
    })
    .catch(response => {
      context.error = response.body
    })
}

login () {
  this.submitButtonLoading = true
  loginService(this, this.credentials)
    .then(_ => {
      this.submitButtonLoading = false
      // ...
    })
}

请注意,无论呼叫是否成功,then()中的login功能都将始终执行。

答案 1 :(得分:0)

要使loginService成为promise,只需在函数内返回Promise即可。确保在功能完成时致电resolve和/或reject

在您的示例中,您可以:

var loginService = function(context, credentials) {
  return new Promise( (resolve, reject) => {
    context.$http.post(LOGIN_URL, credentials, {emlateJSON: true})
      .then(response => {
        if (success) {
          this.user.authenticated = true
          resolve(this.user)
        } else {
          reject(new Error('Log in failed'))
        }
      })
      .catch(err => {
        reject(err)
      })
    })
 }

现在它可以了。

注意整个函数实际上只是返回一个很大的Promise。并且还要注意如何解决或拒绝成功或失败。