什么是Promise

Promise对象是一个构造函数,用来生成promise实例。

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,resolve函数的作用是将Pormise状态变为成功,reject函数的作用是件Promise状态变为失败。

Promise实例生成后可以使用then方法分别指定成功和失败的回调函数。

const promise =  new Promise((resolve, reject)=>{
    // 执行一个异步操作,成功返回data失败返回error
    if(data){
        resolve(data)
    }else{
        reject(error)
    }
})

promise.then((data)=>{
    // 成功的回调
},(error)=>{
    // 失败的回调
})

Promise封装一个ajax请求

var ajax = function(url){
    var promise = new Promise(function(resolve,reject){
        var handler = function(){
            if(this.readyState!==4){
                return
            }
            if(this.status === 200){
                resolve(this.response);
            }else{
                reject(new Error(this.statusText));
            }
        }
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.onreadystatechange = handler;
        xhr.send();
    });
    return promise;
};
ajax('https://www.baidu.com').then((data)=>{
	console.log(data)
},(error)=>{
	
})

Promise的用法

1、基本用法

then

then方法是定义在Promise.prototype上的,它是Promise实例状态改变时的回调函数。第一个参数是成功时的回调函数,第二个参数是失败时的回调函数。

then方法返回一个新的Promise实例,因此可以链式写法(即then后面再跟着一个then方法)。

then链式调用,将结果作为参数传入第二个回调,可以用于先请求一个接口,在请求另一个接口(类似async、await)

promise.then(()=>{
    return 'text'
}).then((data)=>{

})

采用链式的then,可以指定一组按照次序调用的回调函数。这样,前一个回调函数,有可能返回的还是一个promise对象(即有异步操作),这个时候后一个回到函数就会等待该promise对象状态发生改变才会被调用。

catch

catch方法是.then(null, rejection).then(undefined, rejection)的别名,用来指定发生错误时候的回到函数。

Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

getJson.then(()=>{
    return 'something'
}).then((data)=>{

}).catch((error)=>{

})

如上代码,一共有三个promise对象,一个由getJson产生,两个由then产生,他们中的任何一个抛出错误都会被最后一个catch捕获。

finally

finally方法用于指定不管promise对象最后状态如歌,都会执行的操作。

finally方法不接受任何参数,实质上是then方法的特例,且返回原来的值。如下代码:

promise.finally(()=>{
    // 代码
})

promise.then((res)=>{
    // 代码
    return res
},(error)=>{
    // 代码
    throw error
})

2、其他用法

Promise.all

Promise.all将多个promise实例包装成一个新的promise实例。接受一个数组,数组由promise实例组成。数组中的全部promise实例都成功才会成功,有一个失败就会失败。

作为参数的promise实例如果自己定义了catch方法,则一旦被reject,它不会触发Promise.all的catch方法。

Promise.all([p1, p2, p3])

Promise.race

同样是将多个promise实例包装成一个新的promise实例。只有有一个成功即成功,或者有一个失败即失败。

Promise.resolve

Promise.resolve将现有对象转为Promise对象。等价于如下写法:

Promise.resolve('test')

// 等价于
new Promise((resolve,reject)=>{
    resolve('test')
})
  • 参数是一个Promise实例

如果参数是promise实例,则Promise.resolve将不做任何更新,原封不动的返回这个实例。

  • 参数是一个thenable对象

thenable对象值的是具有then方法的对象。Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。

let thenable = {
    then: function(resolve, reject){
        resolve(11)
    }
}
let p = Promise.resolve(thenable);
p.then(function(data){
    console.log(data)
})
  • 参数是不具有then方法的对象或者不是对象

如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。

  • 不带任何参数

Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。需要注意的是,立即resolve()的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

Promise.reject

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

3、Promise和async await

Promise相关问题解答

参考:

[1] ECMAScript 6 入门之Promise

[2] JavaScript Promise:简介

[3] Promise和async await详解

Author:tenado
CeateTime:2019-05-12
Link:https://www.kelede.win/posts/%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3promise/
License:本站博文无特别声明均为原创,转载请保留原文链接及作者
Previous:浏览器缓存机制 Next:输入url后发生了什么