目录
7.构建扁平化的setInterval :实现div向右移动到left=200px停止 开始缩小宽度到10px停止缩放背景变红色
从今天开始我就把自己学习异步编程 promise /async/await的学习做个总结:有新的关于这方面的知识我就会放到里面 博客会不断的更新 我这里总结的都是需要注意的 基础的东西可能不太全 没学过promise可以去看看基础教程promise之后在看这个!
1.首先看下例子:通过文件加载了解任务排序
eg:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
</html>
<script type="text/javascript">
function load(src,resolve){
let script=document.createElement("script");
script.src=src;
script.onload=resolve;
document.body.appendChild(script);
let ele=document.querySelector('script');
console.log(ele.src);
}
load('./1.js',()=>{
load('./2.js',()=>{
two()//
// debugger
})
})
console.log(21121)
//1.js
function one(){
console.log('one');
console.log('1.js文件中的one函数执行完成')
}
//2.js
function two(){
one();
console.log('two');
}
</script>
js是单线程的,文件首先加载主线程同步的任务,从上到下依次执行 :
1.首先打印同步的console.log(ele.src);但是是空值,还没有加载文件完成 这需要一个过程 是个异步执行的宏任务
2.执行console.log(21121)打印
3.加载onload中的函数:1.js文件加载完成加载2.js文件 加载完2.js之后调用2.js中的two函数 two中首先调用了one()函数,one是 1.js文件已经加载完成,所以执行one里面的console.log('one');console.log('1.js文件中的one函数执行完成');之后执行 console.log('two');
截图看加载代码的结果如下:
2.promise.then方法也是一个promise对象
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
<script type="text/javascript">
let p1=new Promise((resolve,reject)=>{
resolve("成功")
})
let p2=p1.then((value)=>{
console.log(value);
},(reason)=>{
console.log(reason);
})
console.log(p1);//Promise {<fulfilled>: "成功"}
console.log(p2);//Promise {<pending>}
setTimeout(()=>{
console.log(p1);//Promise {<fulfilled>: "成功"}
console.log(p2);Promise {<fulfilled>: undefined}
})
/*
** tip:promise.then方法也是一个promise对象
一次打印如下结果:
1.html:19 Promise {<fulfilled>: "成功"}
1.html:20 Promise {<pending>}
1.html:15 成功
1.html:22 Promise {<fulfilled>: "成功"}
1.html:23 Promise {<fulfilled>: undefined}
*/
/*
代码先执行主线程的任务:
1.19/20行打印出来 此时p1是已经执行完了 p2是p1的任务then返回结果promise对象 是个微任务 还没执行
2.之后开始执行p2中的then方法打印"成功"
3.之后开始执行宏任务队列中的setTimeout 此时微任务都执行完毕所以此时 promise都是fulfilled状态
*/
</script>
3.then返回值的处理技巧:then返回promise中的成功或者失败的结果, 在then之后的then返回then中return中的值 如果返回的是promise则返回promise成功或者失败的结果 eg:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
<script type="text/javascript">
//then返回值的处理技巧
/*let p1=new Promise((resolve,reject)=>{
resolve("fulfilled");
})
let p2=p1.then((value)=>{
console.log(value);
// return 'then返回的结果's
}).then((value)=>{
//此时是对P对象的return返回的结果的接收
console.log(value);
},(reason)=>{
console.log(reason);
})*/
let p1=new Promise((resolve,reject)=>{
resolve("fulfilled");
})
.then((value)=>{
console.log(value);//fulfilled
return new Promise((resolve,reject)=>{
setTimeout(()=>{
// resolve('成功')
reject('处理失败')
},1000)
}).then(null,()=>{
//null表示参数 在then使用处理错误前面的参数没有定义会报错 不需要这个就传递null
return new Promise((resolve,reject)=>{
reject('失败了。。。。')
})
})
},(reason)=>{
console.log('error0:'+reason);
})
.then((value)=>{
//此时是对P对象的return返回的结果的接收
console.log(value);
},(reason)=>{
console.log("error1:"+reason);//返回的是promise中的 reject('失败了。。。。')
})
</script>
4.其他类型的promise封装:
tip:返回的只要是对象或者类的方法里面有then就会自动封装册成promise对象 在下一个then中接收这个方法并且处理这个结果
eg:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script>
// 其他类型的promise封装
let p1 = new Promise((resolve, reject) => {
resolve("fulfilled");
}).
then(value => {
/*
*返回的只要是对象或者类的方法里面有then就会自动封装册成promise对象
在下一个then中接收这个方法并且处理这个结果
*/
/* return {
then(resolve, reject) {
setTimeout(() => {
resolve('这是对象')
},3000)
}
} */
/* class Hd{
then(resolve, reject) {
setTimeout(() => {
resolve('这是对象')
},3000)
}
}
return new Hd; */
return class {
static then(resolve, reject) {
setTimeout(() => {
// resolve('这是对象')
reject('失败')
}, 3000)
}
}
}, reason => {
}).then(value => {
console.log(value);
}, reason => {
console.log('error' + reason);
})
</script>
5.用promise封装ajax:
6.封装setTimeout定时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<script>
function timeout(delay=1000){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("参数")
},delay)
})
}
timeout(2000).then(value=>{
console.log('返回数据第一次:'+value);
return timeout(2000)
}).then(value=>console.log("返回数据第二次:"+value))
</script>
7.构建扁平化的setInterval :实现div向右移动到left=200px停止 开始缩小宽度到10px停止缩放背景变红色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 100px;
height: 100px;
background: green;
position: absolute;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
<script>
function Interval(delay = 1000, callback) {
return new Promise((resolve, reject) => {
let id = setInterval(() => {
callback(id, resolve);
}, delay)
})
}
Interval(50, (id, resolve) => {
console.log(122);
let div = document.querySelector('div');
let left = parseInt(window.getComputedStyle(div).left);
div.style.left = left + 10 + 'px';
if (left >= 200) {
clearInterval(id);
resolve(div)
}
}).then((div) => {
Interval(50, (id, resolve) => {
let width = parseInt(window.getComputedStyle(div).width);
div.style.width = width - 10 + 'px';
if (width <= 20) {
clearInterval(id);
div.style.background = 'red';
}
})
})
</script>
8.promise队列原理 上一个promise执行完成之后返回结果下一个promise才执行
let promise=Promise.resolve('成功');
promise=promise.then((v)=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log(1)
resolve('ok')
},1000)
})
})
promise.then((res)=>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log(2);
resolve('ok');
})
})
})
9.async/await语法糖:async 返回promise对象 await 等待的new Promise结果这个执行之后才执行下面的代码
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
async function getNameInfo(){
let name=await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('张三');
},1000)
})
console.log("我是:"+name);
let age=await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(name+":"+'21岁')
},1000)
})
console.log(age);
}
getNameInfo();/*
我是:张三
张三:21岁*/
</script>
</body>
</html>
10.async延时函数:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
async function sleep(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('张三');
// console.log("计时器");
},1000)
})
}
// sleep();
async function getMyUserName(){
for(let user of ["张三","李四"]){
await sleep();
console.log(user);//张三 李四
}
}
getMyUserName();
</script>
</body>
</html>
11.await实现加载进度条:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
.loading{
height:30px;
display: flex;
width:0%;
justify-content: center;
align-items: center;
background: green;
color:#FFF;
}
</style>
</head>
<body>
<div class="loading">0%asdasdsad</div>
<script type="text/javascript">
let load=document.querySelector('.loading');
function sleep(user){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(user)
console.log(user)
},1000)
})
}
async function getMyUserName(users){;
let len=users.length;
for(let user=0;user<len;user++){
await sleep(user);
let progress=((user+1)/len)*100;
load.style.width=progress+"%";
console.log(load.style.width);
load.innerHTML=Math.round(((user+1)/len)*100)+"%";
}
}
getMyUserName(["张三","李四","liuye","送悟空"]);
</script>
</body>
</html>