JS是一门异步单线程非阻塞语言。
如果大量的使用事件,同时要求中间数据能够从一个事件传递到下一个 事件(一般我们认为这就是异步有序),那么我们往往会陷入——金字塔厄运(回调地狱)。
//1.回调=====>"回调地狱"
setTimeout(function () {
console.log("a完成了");
setTimeout(function () {
console.log("b完成了");
setTimeout(function () {
console.log("c完成了");
setTimeout(function () {
console.log("d完成了");
setTimeout(function () {
console.log("b完成了");
setTimeout(function () {
console.log("d完成了");
setTimeout(function () {
console.log("d完成了");
setTimeout(function () {
console.log("b完成了");
setTimeout(function () {
console.log("c完成了");
setTimeout(function () {
console.log("d完成了");
}, 1000)
}, 2000)
}, 1000)
}, 1000)
}, 2000)
}, 1000)
}, 1000)
}, 2000)
}, 1000)
}, 1000)
Promise 是异步编程的一种解决方案
有三种状态:
pending(就绪中)
fulfilled(成功)
rejected(失败)
注: 一旦状态改变,就不会再变,任何时候都可以得到这个结果
romise对象的状态改变,只有两种可能:
从pending变为fulfilled
从pending变为rejected
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject
-resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”
-reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”
.then方法
第一个回调函数是Promise对象的状态变为resolved时调用
第二个回调函数是Promise对象的状态变为rejected时调用
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("a开始了");
resolve(12)
}, 1000)
});
p.then((data) => {
setTimeout(() => {
console.log(`b完成了${data}`);
}, 1000)
})
console.log(p);
Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"一开始是pending
[[PromiseValue]]: 12
返回值是一个promise对象
监听器被触发/时间函数被触发,执行完成后返回的状态发生变化,改变的情况由监听函数执行的返回值决定。
all和race方法
all和race都生成promise对象
let pp=Promise.race([p,p1,p2])
pp.then(()=>{
console.log("hhh");
})
call等所有都完成后才执行;
race有一个完成就执行;
promise.resolve(value)
通过resolve传过来的参数是promise value对象;
var original = Promise.resolve(33);
var cast = Promise.resolve(original);
cast.then(function (value) {
console.log('value: ' + value);
});
console.log('original === cast ? ' + (original === cast));
/*
* 打印顺序如下,这里有一个同步异步先后执行的区别
* original === cast ? true
* value: 33
*/
迭代器/遍历器
提供了一个统一的遍历复杂数据类型的方式arr[Symbol.iterator];
next方法调用得到结果对象;两个属性value,done;
function forof(arr,dal){
let iterator=arr[Symbol.iterator];
let it=iterator.call(arr);
let opt;
while(!(opt=it.next()).done){
dal(opt.value)
}
};
let arr=[1,2,3];
forof(arr,function(v){console.log(v);
})
内置对象中自带遍历器的arry,set,map,string;
使用迭代器的语法有:for。。。of,…扩展运算符。
生成器
Generator 函数是一个普通函数,但是有两个特征:
function关键字与函数名之间有一个星号;
函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”);
function* gen(){
console.log("1");
yield "qq";
console.log("2");
yield 2;
console.log("3");
yield [12211,222]
}
let en=gen()
console.log(en.next());
console.log(en.next());
console.log(en.next());
console.log(en.next());
1
{value: "qq", done: false}
2
{value: 2, done: false}
3
{value: Array(2), done: false}
done: false
value: (2) [12211, 222]__proto__: Object
{value: undefined, done: true}
async await异步函数
所有函数都可以通过加上async关键字变成异步函数;
await只能使用在异步函数中,用来等待promise操作的value;
异步函数的执行结果是一个promise对象,该对象受到函数返回值的影响,参照promise.value;
异步函数的await关键字是有运算结果的,结果是一个promise对象;
async function a() {
console.log(await b());
}
async function b() {
return await new Promise((resolve) => {
setTimeout(() => {
let bb = "bb";
let cc = c()
resolve([cc, bb])
}, 1000)
})
}
async function c() {
return 12
}
a()