js promise是什么?

本文来介绍一下 JavaScript 中的 Promise。(主要讲一下 Promise 的用途)

Promise

Promise 之前的时代——回调时代

假设我们用getUser来取用户数据,它接收两个回调successCallbackerrorCallback

function getUser(successCallback, errorCallback) {
  $.ajax({
    url: '/user',
    success: function(response) {
      successCallback(response)
    },
    error: function(xhr) {
      errorCallback(xhr)
    }
  })
}

这段代码看起来还不算复杂。

如果我们获取用户数据之后还要获取分组数组、分组详情等,代码就成了这样:

getUser(function(response) {
    getGroup(response.id, function(group) {
      getDetails(group.id, function(details) {
        console.log(details)
      }, function() {
        alert('获取分组详情失败')
      })
    }, function() {
      alert('获取分组失败')
    })
  }, function() {
  alert('获取用户信息失败')
})

这是三层回调,如果再多一些嵌套,就是「回调地狱」了。

Promise出现了

Promise的思路是,getUser返回一个对象,我们往这个对象上挂回调:

var promise = getUser()
promise.then(successCallback, errorCallback)

当用户信息加载完毕,这两个回调函数之一就会被执行。

将上面两个语句合并成一句就是:

getUser().then(successCallback, errorCallback)

如果你想在用户信息获取结束后做更多事,可以继续.then

getUser().then(success1).then(success2).then(success3)

请求成功后,会依次执行success1、success2和success3。

如果要获取分组信息:

getUser().then(function(response) {
  getGroup(response.id).then(function(group) {
    getDetails(group.id).then(function() {

    }, error3)
  }, error2)
}, error1)

这种 Promise 写法跟前面的回调看起来其实变化不大。

实际上,Promise 并不能消灭回调地狱,但它可以使回调变得「可控」。

对比下面两个写法就知道了:

getGroup(response.id, success2, error2)

getGroup(response.id).then(success2, error2)

用 Promise 之前,你无法确定success2是第几个参数;

用 Promise 之后,所有的回调都是

.then(success, error)

这样的形式。