1.聊一聊javascript同步和异步编程
1.1什么是异步编程
javascript是同步的,根据 你写的代码一步步执行,连引入js文件 都是同步的(除非用async属性),那不废话吗,肯定根据代码顺序一步步执行嘛,要不乱套了,那这么说java也是同步的咯,在主线程那也没毛病(除非开启多线程)。
那我不得验证一下?读书的时候验证过很多次了,写个js,里面写个死循环,同学电脑都卡死,是你干的不
所谓异步编程就是多线程
1.2为什么要用异步编程
以前不知道异步编程不挺好的,开发这么多年了,不也没出事?
因为你开发的都是去后台拿数据,拿完就显示,ajax默认是异步的,所以一般没啥大问题
但是现在应用不是越来越复杂了嘛,vue,react,typescript,都是为了应对越来越复杂的前端界面。
2.什么是Async和await和promise
async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用Promise。
搞个案例不就懂什么是async和await了么
2.1Async是不是就是多线程
新建一个【新建文本文档.txt】改为【test.html】
console.log("开始测试");
async function testAsync(){
//写个耗时的循环
console.log("执行异步函数开始")
let i=0;
while (i<10000) {
// console.log("执行异步函数结束"+i)
i++;
}
console.log("执行异步函数结束")
return "异步函数的返回值";
}
const result= testAsync();
console.log("结束测试");
输出
开始测试
执行异步函数开始
执行异步函数结束
结束测试
哎哎,这怎么是同步的,没效啊,你不能这样玩啊,javascript,typescript是越来越像java或者c等后端语言了,他是改的像,但并不是啊,那不得从新认识一下javascript
async、await只是一个语法糖,来简化promise,promise是新出来得用来解决异步回调的,async并不能帮你起线程干什么,只是让你使用promise更方便。也可以说是async里面描述的是一个方法体 方法体里面是干await,promise这些事的。
那我明白了async、await是promise的语法糖,promise又是个容器,来控制异步调用的。所以都是来协助我们管理异步调用的,比如 setTimeout,ajax。并不是给我们开启多线程的。
3.promise具体用法
a、处理异步回调
Promise 的基本用法, 处理异步回调。
function Pro1(){
return new Promise(function(resolve, reject) {
setTimeout(function(){
resolve('pro1')
}, 300)
})
}
//调用
Pro1()
.then(function(data){
console.log(data) //pro1
})
.catch(function(err){
throw new Error(err)
})
b、多个异步函数同步处理
有时候我们需要发送两个ajax,希望他们能一起把数据返回,就可以采用下面的办法。
function Pro1(){
return new Promise(function(resolve, reject) {
setTimeout(function(){
resolve('pro1')
}, 300)
})
}
function Pro2(){
return new Promise(function(resolve, reject) {
setTimeout(function(){
resolve('pro2')
}, 300)
})
}
//调用
var Pro = Promise.all([Pro1(), Pro2()]);
Pro
.then(function(data){
console.log(data[0], data[1]) //Pro1 Pro2
})
.catch(function(err){
throw new Error(err)
})
c、异步依赖异步回调
有些场景是一个异步依赖另一个异步的返回值的,就可以采用下面的用法。
比如: 用一个订单号异步取到订单详情,再用订单详情里的商品Id获取到商品详情。
function Pro1(orderId){
return new Promise(function(resolve, reject) {
setTimeout(function(){
var orderInfo = {
orderId: orderId,
productIds: ['123', '456']
}
resolve(orderInfo.productIds)
}, 300)
})
}
function Pro2(productIds){
return new Promise(function(resolve, reject) {
setTimeout(function(){
var products = productIds.map(function(productId){
return {
productId: productId,
name: '衣服'
}
})
resolve(products)
}, 300)
})
}
//调用
Pro1('abc123')
.then(function(productIds){
console.log('商品id',productIds)
return Pro2(productIds)
})
.then(function(products){
console.log('商品详情',products)
})
.catch(function(err){
throw new Error(err)
})
如果这里使用 async 和awit代码量就会少很多,很直观
d、封装统一的入口办法或者错误处理
错误处理
function ErrorHandler(promiseObj, rejectOrResOrCallback){
return promiseObj.then(null, function(err){
if(!err)
})
}
4.javascript异步调用的方式
a.ajax
b.setTimeout,setInterval
c.fetch
d.webwork 开启新线程