Promise 是ES6中新进去的API。其实就是对于回调函数的另一种写法,能够帮忙咱们防止回调天堂。

Promise是一个构造函数,new Promise 返回一个 promise 对象,接管一个带有 resolve 和 reject 两个参数的函数,这个函数在 Promise 构造函数返回所创立 promise 实例对象前被调用。

var p = new Promise(function(resolve, reject) {    resolve() // 胜利时调用    reject() // 失败时调用});p.then(function(res) {    // 从resolve失去失常后果}, function(res) {    // 从reject失去错误信息})

resolve,reject 是一个函数,解决完结后调用 resolve 或 reject。当调用resolve,会把以后promise对象状态由 pending 标记胜利(fulfilled),当调用 reject,会把状态由 pending 标记失败(rejected)。

Promise的三种状态

  • pending :挂起,以后promise执行的工作,正在执行中
  • fulfilled: 实现,以后promise对象执行的工作,曾经实现,并且是胜利状态
  • rejected: 实现,以后promise对象执行的工作,曾经实现,并且处于失败的状态

封装一个反对Promise API的延时函数:

function timeOut(time){    // 这个函数中就须要返回一个Promise对象    return new Promise((resolve, reject) => {        setTimeout(function(){            // resolve和reject在调用的时候,是能够传递数据的,这个数据会最终被传递到胜利或者失败的回调函数中            resolve(123)            // resolve()            // reject()        }, time)    })}

基于Promise解决Ajax申请:

function queryData(url) {    return new Promise(function(resolve, reject){        var xhr = new XMLHttpRequest();        xhr.onreadystatechange = function() {            if(xhr.readystate !== 4) return;            if(xhr.readystate === 4 && xhr.status === 200){                resolve(xhr.responseText);            }else{                reject('出错了');            }        }        xhr.open('get', url);        xhr.send(null);    })}queryData('http://localhost:3000/data')    .then(function(res){        console.log(res);    }, function(err){        console.log(err)    })//发送屡次申请queryData('url1')    .then(function(data){        return queryData('url2');    })    .then(function(data){        return queryData('url3');    })    .then(function(data){        console.log(data);    })

当 Promise 对象的 fulfilled 或 rejected 任一状态呈现时,就会调用 Promise 对象的 .then 办法中绑定的函数。

then 参数中的函数返回值:

  1. 返回 Promise 实例对象

    • 返回的该实例对象会调用下一个 then
  2. 返回一般值

    • 在then办法中,能够间接 return 数据而不是Promise对象
    • 返回的一般值会间接传递给下一个 then,通过 then 参数中函数的参数承受该值

罕用API:

  • .then() 失去异步工作的胜利信息
Promise    .then(        function() {            console.log('胜利的回调')        },        function() {            console.log('失败的回调')        }    )
  • .catch() 获取异样信息
Promise    .then(function() {        console.log('胜利的回调')    })    .catch(function() {        consloe.log('失败的回调')    })

成果和写在then的第二个参数外面一样。不过它还有另外一个作用:在执行resolve的回调(也就是下面then中的第一个参数)时,如果抛出异样了(代码出错了),那么并不会报错卡死,而是会进到这个catch办法中。

  • .finally() 胜利与否都会执行(还不是正式规范)
  • Promise.all() 并发解决多个异步工作,所有工作都执行实现才执行回调函数
const p1 = new Promise((resolve, reject) => {    resolve(1)})const p2 = new Promise((resolve, reject) => {    resolve(2)})const p3 = new Promise((resolve, reject) => {    resolve(3)})Promise    .all([p1, p2, p3])    .then(res => {        console.log("所有异步操作实现了", res) //res: 三个后果的数组,后果程序和promise实例数组程序是统一的    })    .catch(err => {        console.log(err)    })
  • Promise.race() 只有有一个工作实现就会执行回调失去后果
Promise    .race([p1, p2, p3])    .then(res => {        console.log("有一个异步率先实现了", res)    })

拓展 async/await 的根本用法

async 和 await 这两个关键字是es7提供的,它们能够将Promise的写法进行简化,async和 await 必然同时呈现(有 await 必然会有 async)。

  • async 关键字用于函数上(async 函数的返回值是 Promise 实例对象)
  • await 关键字用于 async 函数中(await 能够失去异步的后果)
async function queryData(id){    const ret = await axios.get('/data');    return ret;}queryData.then(ret => {    console.log(ret);})

多个异步申请的场景

async function queryData(id){    const info = await axios.get('/async1');    const ret = await axios.get(`/async2?info=`+info.data);    return ret;}queryData.then(ret => {    console.log(ret);})

async 和await异样的解决(失败的回调) 应用 try和catch即可

语法:

try {     // 胜利的回调 } catch(err) {    // 失败的回调}

例:

async deleteUser(id) {    // 胜利的回调    try {        await this.$confirm("此操作将永恒删除该文件, 是否持续?", "提醒", {            confirmButtonText: "确定",            cancelButtonText: "勾销",            type: "warning"        })        let res = await this.$http({            url: `users/${id}`,            method: "delete",            data: id        })        console.log(res)        if (res.data.meta.status === 200) {            console.log('success', res)        }    }     // 失败的回调    catch (err) {        console.log('已勾销删除')    }}