2017-11-06 技术分享

概念

ES6 原生提供了 Promise 对象。 所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

特点

1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。

2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。

基本的 api

  • Promise.resolve()
  • Promise.reject()
  • Promise.prototype.then()
  • Promise.prototype.catch()
  • Promise.all()
  • Promise.race()

(以上都是抄的)

一个简单的 promise

var promise = new Promise( (resolve, reject)  =>{
    // 需要异步做的事情
    if (success) {
        // 改变 promise 的状态为已完成
        resolved('已完成')
    } else {
        rejected ('失败')
    }
})

promise.then(res => {
    // 处理异步完成后的数据 res
}).catch(function (e) {

    console.log(e)

})

一个简单的基于 Promiseajax

使用原生 XHR 发起请求,请求成功将 promise 状态从 pending 变为 resolved ,并将 promise 对象return出来

function ajax(options) {
    return new Promise(function (resolve, reject) {
       var setting = {}
       for (var k in options) {
         setting[k] = options[k]
       }
        var xhr = new XMLHttpRequest()
        xhr.open(options.method, options.url, options.async || true)
      xhr.send(options.method === 'get' ? '' : data)
         xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                resolve(xhr)
            }
        }
    })
}

// 调用

ajax({
    method: 'get',
    url: url
}).then(function (data) {
    var res = JSON.parse(data.response)
    return res
})

promise 是一个非常好也非常有用的东西,链式调用解决了 ajax 回调地狱的情况,Promise是一个构造函数,在其原型链上有then, catch等方法具体的介绍,可以参照阮一峰的Promise对象介绍

demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button id="getData">获取用户名称</button>
</body>
</html>

点击获取用户名称发起请求获取用户数据

调用

var page = 0
document.getElementById('getData').onclick = function () {
    page ++
    ajax({
        method: 'get',
        url: 'http://101.37.33.134:18888/mall/rsUser?pageNumber='+ page +'&pageSize=10'
    }).then(function (data) {
        var res = JSON.parse(data.response)
        console.log(res.data.records)
        for (var i = 0; i < res.data.records.length; i++) {
            document.getElementById('app').innerHTML += '<div>'+ res.data.records[i].realName +'</div>'
        }
    })
}

点击按钮调用 ajax 方法,得到promise 对象通过 promisethen 方法进行链式回调,就可以在回调内取到数据进行处理

以上