JavaScript最早设计初衷:运行在浏览器端的脚本语言,为了实现页面上的动态交互,实现页面交互的核心就是操作dom,假如是多线程模式就会出现线程同步问题:
多个线程一起工作,一个修改dom,一个删除dom,浏览器不知道先执行哪一个
避免这种线程同步问题,JavaScript只能是单线程
单线程:执行代码的线程只有一个
优点:安全 简单
缺点:耗时任务可能造成假死现象
于是JavaScript将任务的执行模式分成了两种:同步模式、异步模式
依次执行 后一个等待前一个结束后在执行
1.不会等待任务结束才开始下一个任务
代码执行顺序混乱
2.回调函数:
将函数作为参数传入,在异步任务结束后执行
回调函数是JavaScript中所有异步模式的根基
function foo(callback){
setTimeout(function(){
callback()
},1000)
}
3.Promise
一、为了解决回调地狱问题
三种状态,一旦变成fulfilled或者rejected之后就不会再改变了
二、基本用法
const promise = new Promise(function(resolve,reject){
// resolve(100) //承诺达成
reject(new Error('promise reject')) //承诺失败
})
promise.then((value)=>{
//.then方法第一个参数为成功的回调,第二个参数为失败的回调
console.log('resolved',value);
},(error)=>{
console.log('rejected',error);
})
三、使用案例
封装Ajax请求:
function ajax(url){
return new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest();
xhr.open('GET',url);
xhr.responseType = 'json';
xhr.onload = () => {
if(this.status === 200){
resolve(this.response)
}else{
reject(new Error(this.statusText))
}
}
xhr.send()
})
}
四、链式调用
.then返回的是一个全新的promise对象 所以可以使用链式调用的方法添加then方法
后面的then方法就是在为上一个then方法返回的promise对象注册回调
前面then方法中回调函数的返回值会作为后面then方法回调的参数
如果回调中返回的是Promise,那后面then方法的回调会等待它的结束
五、异常处理
除了使用.then方法的第二个参数回调,.catch 方法也可以处理异常,更常用,更符合链式
const promise = new Promise(function(resolve,reject){
// resolve(100) //承诺达成
reject(new Error('promise reject')) //承诺失败
})
promise
.then((value)=>{
//.then方法第一个参数为成功的回调,第二个参数为失败的回调
console.log('resolved',value);
return '1'
})
.catch((error)=>{
console.log('rejected',error);
return 'err'
})
.then 和.catch捕获异常的区别:
.then 捕获异常只能捕获当前promise的异常
.catch 捕获可以捕获整个promise链上的异常
做个题:
六、Promise的静态方法
1.resolve
快速的把一个值转换为promise对象
2.reject
快速构建一个失败的promise对象
七、Promise并执行
promise.all 将多个promise合并为一个promise
返回一个全新的promise对象,当所有promise都完成之后这个全新的promise才算完成,拿到的结果是一个数组。
promise.race 将多个promise合并为一个promise
返回一个全新的promise对象,当有一个promise完成之后这个全新的promise就算完成,拿到的结果是第一个完成promise的结果。
八、Promise执行时序
宏任务执行过程中临时加入的额外任务可以作为一个新的宏任务进到队列中排队也可以作为当前任务的微任务直接在当前任务结束后立即执行
宏任务主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、
setImmediate(Node.js 环境)
微任务主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)
九、Generator
function * foo(){
console.log('start');
const res = yield 'foo'
console.log('返回值===>参数',res);
yield 'oo'
}
const generator = foo();//直接调用后并不会立即执行 而是会得到一个生成器对象
const result = generator.next();//调用next方法才会执行 并返回yield后的值 并且暂停
console.log('result',result,generator.next('参数')); //result {value: "foo", done: false} {value: "oo", done: false}
十、async
async function main(){
try{
const users = await ajax('./api/urls.json');
console.log('user',users);
} catch(e){
console.log('e',e);
}
}
const promise = main();//async 返回一个promise
promise.then(()=>{
console.log('all ok');
})