理解javascript中的Promise

432 阅读2分钟

1.什么是Promise

Promise是异步操作的占位符。他代表一个未来有希望获得的值。一个promise对象的生命周期中,从等待pending状态开始,在程序执行过程中,如果promise的resolve函数被调用,promise就会进入完成状态(fulfilled)。如果promise的reject函数被调用,promise就会进入拒绝状态(rejected)。

2. Promise的执行顺序

同步代码及new Promise构造函数按代码顺序执行完后,再执行then回调函数来处理promise。

console.log('at code start')
var ninjaDelayedPromise = new Promise((resolve, reject) => {
    console.log('ninjaDelayedPromise execute');
    setTimeout(() => {
        console.log('resolving ninjaDelayedPromise ')
        resolve('ninjaDelayedPromise')
    }, 500)
})
console.log('after create ninjaDelayedPromise ')
ninjaDelayedPromise.then(res => {
    console.log(res)
})

var ninjaImmediatedPromise = new Promise((resolve, reject) => {
    console.log('ninjaImmediatedPromise execute');
    resolve('ninjaImmediatedPromise')
})
console.log('after create ninjaImmediatedPromise ')

ninjaImmediatedPromise.then(res => {
    console.log(res)
})
console.log('at code end')
//输出结果
//> "at code start"
//> "ninjaDelayedPromise execute"
//> "after create ninjaDelayedPromise "
//> "ninjaImmediatedPromise execute"
//> "after create ninjaImmediatedPromise "
//> "at code end"
//> "ninjaImmediatedPromise"
//> "resolving ninjaDelayedPromise "
//> "ninjaDelayedPromise"

3. 拒绝Promise

a.显示拒绝promise

const promise = new Promise((resolve, reject) => {
    reject('reject a promise')
})

b.异常隐式拒绝promise

const promise = new Promise((resolve, reject) => {
    undeclaredVariable++;//未定义的变量自加会发生异常,promise会隐式拒绝
})

c.then方法第二个回调函数处理拒绝promise

promise.then(res=>console.log(res), error => console.log(error))

d.链式调用catch方法处理拒绝promise

promise.then(res=>console.log(res)).catch(error=>console.log(error))

4.链式调用promise

promise可以链式调用,在promise上使用then函数,调用then方法后可以再返回一个新的promise对象。promise后面可以调用许多then方法,实现异步操作的链式调用如果没有发生任何错误,则程序流程只会无阻碍的继续执行,如果任何一步出现错误,使用catch捕获promise链中的错误。

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function (comments) {
  return getJSON(comments.url);
}).then(function(res){
  console.log(res)
}).catch(function (err){
  console.log("rejected: ", err);
});

5.等待多个promise

使用Promise.all方法等待多个promise,该方法将一个promise数组作为参数,然后创建一个新的promise对象,一旦数组中的promsie全部被解决,这个返回的promise就会被解决,而一旦其中有一个promise失败了,那么整个新的promise对象也会被拒绝。后续的回调函数接受成功值组成的数组,数组中的每一项都对应promise数组中的对应项。

Promise.all([getJson('data/ninjas.json'), 
            getJson('data/mapInfo.json'),
            getJson('data/plan.json')]).then(results => {
                console.log(results[0])
                 console.log(results[1])
                  console.log(results[2])
            })

6.promise竞赛

Promise.race方法只关心第一个成功(或失败)的promise,使用Promise.race方法传入一个promise数组会返回一个全新的promise对象,一旦数组中某一个promise被处理或拒绝,这个返回的promise就同样被处理或拒绝

Promise.race([getJson('data/ninjas.json'), 
            getJson('data/mapInfo.json'),
            getJson('data/plan.json')]).then(res =>{
                console.log(res + 'is first respond')
            }).catch(err => {
                console.log(err)
            })