ES6新增用于异步编程,支持链式调用,可以解决回调地狱问题
原生Dom操作js下的 Promise实例。 用 Promise 封装一个异步的操作,然后在成功时调用 resolve() 函数,并把成功的结果传递给成功的回调,在失败时调用 reject() 函数,并将失败的原因和错误传递给失败的回调,最后在 then() 方法中,对成功和失败的结果进行处理,

const  p = new Promise((resolve, reject) => {
    setTimeout(() => {
        // do something
        if(result == true) {
            resolve();    // 意为将 promise 对象的状态置为   成功  括号内可传递参数,在then成功回调函数中进行接收
        } else {
            reject();    // 意为将 promise 对象的状态置为   失败  括号内可传递参数,在then失败回调函数中进行接收
        }
    }, 1000)
})

// 用then方法指定回调成功和失败 的下一步操作
p.then(() => {
        // 此处为上面 resolve() 执行成功的回调
}, () =-> {
        // 此处为上面 reject() 执行失败的回调
});

tp: resolve() reject() 方法是属于 Promise 的方法, then() catch() 是属于 Promise 实例化对象上的方法

promise 状态 promiseState

状态是指 promise 实例对象中的一个属性 promiseState , 状态一共有三种值的形式
pendding (初始化,默认值, 未决定的)
resolved / fullfilled
rejected
只存在两种可能的状态 pending ---> resolved pending ---> rejected 且状态只能改变一次
throw抛出异常或者任何异常情况 ---> rejected

promise 对象的值 promiseResult

实例对象中的另一属性 promiseResult
保存着异步任务 成功 或 失败的结果
resolve
reject

promise 工作流程

首先,new Promise() 构造函数得到实例,此时 promise 状态为初始值 pendding, 然后执行异步操作,得到异步操作的结果,如果异步操作成功则执行 resolve 函数,将 promise 状态修改为 resolved ,并在后续新的实例对象调用的 then 方法回调中执行成功的操作。 如果异步操作执行失败则执行 reject 函数,将 promise 状态由pendding更改为 rejected ,并在后续新的实例对象调用的 then 方法回调中执行失败的操作

catch 方法和 then() 方法使用方法一样,但是 catch 只可以指定失败的回调

Promise.resolve() and Promise.reject()

let p1 = Promise.resolve(222);'
// 如果传入的参数为 非 Promise 类型的对象,则返回的结果为成功的 promise 对象
// 如果传入的参数为 promise 对象,则参数的结果决定了 resolve 的结果
let p2 = Promise.reject(212)
// Promise.reject() 方法不论传入什么参数,都会返回 rejected 失败的结果 传入什么,失败的结果就是什么

Promise.all()

Promise.all() 方法接收一个数组,数组中可以包含多个 promise 实例对象,只有当所有的 promise 实例对象都为 resolved 时,才会返回一个由多个实例对象结果组成的数组,只有有其中一个为 rejected 状态,则所有的都为 rejected

Promise.race()

Promise.race()  方法接收一个数组,返回的值为一个新的 promise 对象,第一个完成的 promise 结果状态就是最终的结果状态

Promise执行多个回调

当一个promise 改变为对应的状态的时候,所属状态的回调都会被调用

Promise 执行后改变状态 和 执行回调 谁先谁后

当一个 promise 对象是 同步 进行的时候, 也就是自上至下执行时,会先改变 promise 的状态,后执行回调函数
而当改变状态这一步操作被包裹在定时器之类的 异步 操作之中时,会造成阻塞,需要等到异步的变更状态结束后才回去执行回调函数里的内容

let p = new Promise((resolve, reject) => {
    //此时,由于改变状态的这异步操作被包裹在定时器中,成为了异步操作,此时就会先执行回调函数,后改变状态
    setTimeout(() => {
        reject('ok')
    }, 1000)
})
p.then(value => {
    console.log(value)
}, reason => {

})

Promise then方法的返回结果

let p = new Promise((resolve, reject) => {
    resolve('ok')
})
let result = p.then(value => {
    // 1,此处在成功的then方法抛出异常,promise对象的状态会变成rejected
    throw ‘有问题’
    //2,如果此处直接 return 一个 非Promise类型的对象或值,新的promise 对象的状态为 resolved, value为 return 出去的值 
    return 'hello'
    //3,如果返回的是另一个新的promise,此promise的结果就会变成新promise的结果和状态
    return new Promise((resolve, reject) => {
        reject('err')
    })
}, reason => {

})

Promise 串联多个任务

let p = new Promise((resolve, reject) => {
        resolve('111')
    })
    p.then(value => {
        return new Promise((resolve, reject) => {
            <!-- resolve('222') -->
            // 如果开头或中间某一环节调用 reject,,导致中断, 则不会再调用后面的回调函数,直接终止
            reject('222')
        })
    }).then(value => {
        // console.log(value)
        // 此时打印获取到的 value 就是上一个 promise 执行完后的结果值 222
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('333')
            },2000)
        })
    }).then(value => {
        // 此时打印获取得到的 value 就是上一个异步操作定时器执行完成之后的值 333
        console.log(value)
    })

Promise 异常穿透

在promise链式调用时,如果在开头或中间的某一环节,调用了失败的 promise 回调,或者抛出异常,就会直接返回失败的 promise 对象并终止其他的 promise 链式上的操作。可以通过异常捕获进行规避,在then 的调用链的最后 加上一个 .catch(reason => {}) 就可以进行异常的处理,并且 promise 具有异常穿透的特征,不管在中间的那个环节 抛出错误 都能在 .catch 中进行捕获和处理

如何中断 Promise 链式调用

在 then 链式调用过程中,想要前面的正常执行, 后面的后一环节之后的不再执行,也就是中断链式调用的话,只是单纯的返回 失败状态或者抛出异常之类的是不行的,这种方式没办法让中断处之前的正常执行,而是全盘否认,此时有且只有一种方式解决,就是返回一个 promise 状态为 pendding ,此时pendding 状态为 未指定 就不会再往下执行其他操作

p.then(value => {
    console.log('1')
    // 此时想要 终止 后续的链式调用,只有一个方法,就是将 promise 的状态置为 pendding,就会中断链式调用,不再执行后续操作
    return new Promise(() => {});
}).then(value => {
    conosle.log('2')
}).then(value => {
    console.log('3')
}).catch(reason => {
    conosle.log(reason)
})