一、JavaScript 异步编程
内容概述
- 同步模式与异步模式
- 事件循环与消息队列
- 异步编程的额几种方式
- Promise 异步方案、Async / Await 语法糖
二、同步模式
1.概念
同步模式指的就是我们代码中任务依次执行,后一个任务必须等待前一个任务执行完毕之后能开始执行,执行的顺序就和代码中的顺序是一样的,比较简单。
二、异步模式
1.概念
和同步模式相反:它不会等待这个任务的结束才开始下一个任务,开启任务之后会立即执行下一个任务,异步的后续操作一般都是通过回调函数的方式定义
2.作用
没有异步模式,JavaScript 就无法同时去处理大量耗时的任务。
3.难点
代码执行顺序混乱
4.回调函数
回调函数是所有异步编程的根基,把回调函数给执行者,执行者会在任务完成后再去执行函数,这种叫回调函数。
三、Promise
1.Promise 基本示例
const promise = new Promise(function(resolv, reject){
// resolv(100);
reject(new Error('promise reject'))
})
promise.then(function(val){
console.log(val);
},function(val){
console.log(val);
}
2.Promise 方式的 AJAX
function ajax(url){
return new Promise(function (resolv, reject) {
let xhr = new XMLHttpRequest;
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = function(){
if (this.status === 200) {
resolv(this.response)
} else {
reject(new Error(this.statusText));
}
}
xhr.send()
})
}
// ajax('api').then(function (params) {
// console.log(params);
//},function (params) {
// console.log(params);
//})
ajax('api')
.then(function (params) {
console.log(params);
})
.catch(v=>{
console.log(v)
})
3.Promise 链式调用
- Promise 对象的 then 方法会返回一个全新的 Promise 对象
- 后面的 then 方法就是在为上一个 then 返回的 Promise 注册回调
- 前面 then 方法中回调函数的返回值会作为后面 then 方法回调的参数
- 如果回调中返回的是 Promise ,那后面的 then 方法的回调会等待它的结束
function ajax(url){
return new Promise(function (resolv, reject) {
let xhr = new XMLHttpRequest;
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = function(){
if (this.status === 200) {
resolv(this.response)
} else {
reject(new Error(this.statusText));
}
}
xhr.send()
})
}
ajax('api').
then(function (params) {
console.log(params);
return ajax('xxxx')
}.then(function (params) {
console.log(params);
return ajax('xxxx')
}).function (params) {
console.log(params);
return ajax('xxxx')
}
4.Promise 静态方法
let promise = ajax('url');
promise.resolve({
then:function (onFulfilled, onRejected) {
onFulfilled('foo')
}
})
.then(function(val){
console.log(val);
})
promise.reject({
then:function (onFulfilled, onRejected) {
onFulfilled('foo')
}
})
.catch(function(val){
console.log(val);
})
5.Promise 并行执行
//promise.all方法 等待所有接口结束请求, 如果有异常就返回异常
var promise = new Promise.all([
ajax('url1'),
ajax('url2')
])
promise.then(function (values){
console.log(values) // 数组
}).catch(function (error){
console.log(error) // 数组
})
// promise.race() 只会等待第一个方法结束
var promise = new Promise.race([
ajax('url1'),
ajax('url2')
])
promise.then(function (values){
console.log(values) // 数组
}).catch(function (error){
console.log(error) // 数组
})
四、Generator 异步方案
1.示例流程
function * foo(){
console.log('start');
try {
const res = yield 'foo';
console.log(res);
} catch (e) {
console.log(e + '1');
}
}
const generator = foo();
const result = generator.next(); // 只执行函数体内的 yield 处并返回给 result
console.log(result); // { value: 'foo', done: false }
generator.next('bar'); // 再次执行 返回给 res 并且执行下面的方法
generator.throw(new Error('Generator error')); // 报错
2.Generator 和 Promise 配合完成多个回调(用yield 返回的done为ture时结束)
function * main () {
const user = yield ajax('url1');
console.log(user);
const posts = yield ajax('url2');
console.log(posts);
}
const g = main();v
const result = g.next()
result.value.then( v => {
const result2 = g.next(v);
if (result2.done) return
result2.value.then(data => {
const result3 = g.next(data)
if (result3.done) return
result3.value.then(data => {
const result3 = g.next(data)
if (result3.done) return
// ... 递归
} )
})
})
五、Async / Aait 语法糖
async function foo(){
console.log('start');
try {
const res = await 'foo';
console.log(res);
} catch (e) {
console.log(e + '1');
}
}
const promise = foo();
promise.then(v=>{
console.log(v)
})