promise的使用

promise的使用

  • promise实现ajax封装
  • 捕获异常
  • 返回promise对象
  • Promise.all()组合请求
  • Promise.race()实现超时
  • Promise.resolve()
    • 参数为thenable实例

promise实现ajax封装

var getJson = function (url) {
    return new Promise(function (resolve, reject) {
        var client = new XMLHttpRequest()
        client.open("GET", url)
        client.onreadystatechange = handler
        client.responseType = "json"
        client.setRequestHeader("Accept", "application/json")
        client.send()

        var handler = function () {
            if (this.readyState !== 4) {
                return;
            }
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
    })
}

getJson("http://localhost:3000/news")
    .then(function (data) {
        console.log(data)
    }).catch(function (err) {
        console.log(err.stack)
    })

捕获异常

var promise = new Promise(function (resolve, reject) {
    throw new Error("error")//等同于reject(new Error("error")),会回调catch中的方法
    resolve('ok')
})
promise.catch(function (err) {
    console.log(">>>>>", err.message)
})
>>>>> error

一旦状态由pending转为fullfilled或者rejected,后面的语句即使报错也不会被捕获,等同于没有抛出

var promise = new Promise(function (resolve, reject) {
    resolve('ok')
    throw new Error("error")
})
promise.catch(function (err) {
    console.log(">>>>>", err.message)
})
#无任何输出

返回promise对象

当resolve处理函数返回另外一个promise时,后面的resolve处理函数then将直接得到第二个promise的成功返回结果

getJson("http://localhost:3000/news?id=1")
    .then(function (data) {
        return getJson("http://localhost:3000" + data.commentsUrl)
    })
    .then(function (data) {
        console.log(JSON.stringify(data))
    })
    .catch(function (err) {
        console.log(">>>>>>", err.message)
    })
[{"id":1,"content":"comment content1111...","newsId":"1"},{"id":2,"content":"comment content2222...","newsId":"1"}]

值得注意的是catch会捕获两个then中抛出的异常

getJson("http://localhost:3000/news?id=1")
    .then(function (data) {
        return getJson("http://localhost:3000" + data.commentsUrl)
    })
    .then(function (data) {
        throw new Error("第二个then抛出异常")
        console.log(data)
    })
    .catch(function (err) {
        console.log(">>>>>>", err.message)
    })
第二个then抛出异常

Promise.all()组合请求

利用Promise.all()可以组合多个promise成为一个新的promise,并将在所有promise变成Fullfilled后该promise才会变成Fullfilled状态并触发then方法

var promises = [1, 2, 3].map(function (id) {
    return getJson("http://localhost:3000/news?id=" + id)
})

Promise.all(promises).then(function (posts) {
    console.log(JSON.stringify(posts))
})
[{"id":"1","title":"news title1...","content":"news content1...","commentsUrl":"/comments?newsId=1"},
{"id":"2","title":"news title1...","content":"news content1...","commentsUrl":"/comments?newsId=2"},
{"id":"3","title":"news title1...","content":"news content1...","commentsUrl":"/comments?newsId=3"}]

浏览器实际发出三次请求
promise的使用_第1张图片

Promise.race()实现超时

race是竞速的意思,顾名思义谁先打到fullfilled或rejected条件谁先触发回调函数

var timeoutPromise = new Promise((resolve, reject) => {
    setTimeout(() => reject("Time out"), 10) //10ms
})

Promise.race([getJson("http://localhost:3000/news?id=2"), timeoutPromise])
    .then(data => console.log(JSON.stringify(data)))
    .catch(err => console.log(err))

Promise.resolve()

将现有对象转化为promise对象

参数为thenable实例

thenable实例即为有then方法的实例

var thenable = {
    then: function (resolve, reject) {
        resolve(111)
    }
}
Promise.resolve(thenable)
    .then(data => console.log(">>>>", data))

你可能感兴趣的:(前端,javascript)