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 参数中的函数返回值:
-
返回 Promise 实例对象
- 返回的该实例对象会调用下一个 then
-
返回一般值
- 在 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('已勾销删除')
}
}