目录
一、promise使用
在JavaScript的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现.
div.onclick = function(){}
Promise使ES6中引入的一个异步编程解决方案,与传统的ES5方法相比它的结构更合理,功能更强大.
特点:
Promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态.
基本使用:
var p = new Promise(function(resolve,reject){})
resolve 代表 决定(成功); reject 代表 失败基本使用:
const p = new Promise(function(resolve,reject){
setTimeout(function(){
// resolve('我是成功的')
reject('这是失败的');
},2000)
});
.then(callback)的使用(成功时调用)
.catch(callback的用法(失败时调用)
p.then(function(data){
console.log('resolved成功回调');
console.log('成功回调接受的值:',data);
}).catch(function(reason, data){
console.log('catch到rejected失败回调');
console.log('catch失败执行回调抛出失败原因:',reason);
});
效果和写在then的第二个参数里面一样。它将大于10的情况下的失败回调的原因输出
注意:resolve和reject的两种状态
resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
二、静态方法的使用
promise并非一开始就必须处于待定的状态,然后通过执行器函数才能转化为成功或失败.也可以直接调用resolve和reject方法.
Promise.resolve()
let p1 = new Promise((resolve,reject)=> resolve());
let p1 = new Promise((resolve,reject)=> resolve());
let p2 = Promise.resolve()
// 两种方式结果是一样的.都表示状态切换到成功
Promise.reject()
let p1 = new Promise((resolve,reject)=> reject());
let p2 = Promise.reject()
// 都表示状态切换到失败
Primise.finally()
let p1 = new Promise((resolve,reject)=> reject());
let p2 = Promise.reject()
// 都表示状态切换到失败
Primise.finally()
该方法无论期约为成功或者失败都可以调用,主要是表面then和catch当中出现冗余的代码.但它无法知道状态是成功还是失败,因此该方法主要用于添加清理代码.
let p1 = Promise.resolve();
let p2 =Promise.reject(); // 错误没有被处理 Uncaught (in promise)
p1.finally(function(){
console.log('被调用...');
})
p2.finally(function(){
console.log('可以...');
})
三、期约的合并
Promise.all()
所有的异步请求完成才执行的方法.
Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。
let wake = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${time / 1000}秒后醒来`)
}, time)
})
}let p1 = wake(3000);
let p2 = wake(2000);Promise.all([p1, p2]).then((result) => {
console.log(result) // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
console.log(error)
})
只有两次调用promise都执行完毕,才会执行all
Promise.race()
Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})
四、async 和await的使用
+ 只是对 Promise 语法的一种增强书写方式
+ 注意: 作用, 为了把异步代码写的看起来像同步async 关键字
+ 在函数前面书写
+ 作用: 为了在该函数内可以使用 await 关键字await 关键字
+ await 后面等待的必须是一个 Promise 对象
+ 目的: 为了等到 后面的 Promise 执行完毕在继续执行下一行代码
+ 作用: 本来应该在 then 里面接受的结果, 可以直接定义变量接受了
+ 解析:当js运行遇到await关键字时,会记录在哪里暂停执行,等await右边的值可用时,js会想消息队列推送任务,这个任务恢复异步的执行.
怎没用?
async function fn() {
console.log('start')
// 等着第一个请求
const r1 = await pAjax({ url: 'http://localhost:8888/test/first' })
console.log(r1)// 如果上面的 请求没有结束, 那么这里的代码不会执行
// 这里的代码执行了, 一定是因为 await 等到了上面的请求结束
const r2 = await pAjax({ url: 'http://localhost:8888/test/second', dataType: 'json' })
console.log(r2)const r3 = await pAjax({ url: 'http://localhost:8888/test/third', data: 'name=Jack&age=20', dataType: 'json' })
console.log(r3)console.log('end')
}