1、回调函数解决无法访问异步函数中的值问题
这种回调函数的方法实际上适用于依赖异步处理程序的code
实际上是将回调函数也跟着异步了,所以能和异步操作同步
function getData(callback) {
setTimeout(() => {
var name = 'JOJO';
callback(name);
return name;
}, 2000)
}
function callback(name) {
console.log(name);
}
console.log(getData(callback));
2、发布订阅模式
document.body.addEventListener('click',function(){
alert(2);
},false);
document.body.click(); //模拟用户点击
let fs = require('fs');
let dep = {
arr: [],//保存回调函数
on(callback){
this.arr.push(callback);
},
emit(){
this.arr.forEach(item=>{
item();
})
}
}
let school = {};
//这里先加一个回调函数 (订阅)
dep.on(function(){
if(Object.keys(school).length === 2){
console.log(school);//{ name: 'cjw', age: '18' }
}
})
//
fs.readFile('./age.txt', 'utf8', function(err, data){
school['name'] = data;
dep.emit();//发布,调用dep.arr 里面的回调函数一一执行
})
fs.readFile('./name.txt', 'utf8', function(err, data){
school['age'] = data;
dep.emit();//发布
})
3、promise解决无法访问异步函数中的值问题
实际上promise的原理就是发布订阅方式
promise以同步的方式写异步,它是一个对象 参数是一个函数 ,函数有两个参数 resolve reject
new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise;
resolve 成功
reject 拒绝
then(a,b) a,b 就是两个函数对象 a就是reslove b就是reject
var p = new Promise(function(resolve, reject) {
setTimeout(() => {
var name = 'JOJO2';
resolve(name);
}, 2000)
}).then((data) => {
console.log(data);
})
4、promise.all的使用
var p1 = new Promise(function(resolve, reject) {
setTimeout(() => {
var name = 'JOJO';
resolve(name);
}, 2000)
})
var p2 = new Promise(function(resolve, reject) {
setTimeout(() => {
var name = 'JOJO2';
resolve(name);
}, 2000)
})
Promise.all([p1, p2]).then((arr) => {
console.log('成功');
console.log(arr);
}, () => {})
5、函数包装进阶
function cPromis(pname) {
let p = new Promise((res, rej) => {
setTimeout(() => {
let name = pname;
res(name);
}, 2000)
})
return p;
}
p1 = cPromis("JOJO");
p2 = cPromis("DIO");
Promise.all([p1, p2]).then((arr) => {
console.log('成功');
console.log(arr);
}, () => {})
6、await和async
async function test() {
return 'JOJO';
}
function test2() {
return "DIO";
}
async function test3() {
let b4 = await test(); //await只能用在异步方法中
//获取 异步方法中的值
console.log(`b4:${b4}`);
return b4 //jojo
}
let b1 = test(); //返回的是一个promise对象
let b2 = test2();
let b3 = test3();
console.log(`b1,${b1} b2:${b2}, b3:${b3}`);
console.log('JOJO');
//b1,[object Promise] b2:DIO, b3:[object Promise]
输出为
b1,[object Promise] b2:DIO, b3:[object Promise]
JOJO
b4:JOJO
可见,在执行函数test3中,等待了另外一个异步函数test执行完毕
在执行test3时,遇到了await,test3函数立即返回一个promise对象待处理,然后处理await后面的异步函数,等await后面的异步函数处理完毕,再处理test3
7、深入理解await与async
请看下面啊的例子
sync function k1(){
console.log('1、k1');
return 'JOJO';
}
async function k2() {
console.log('2、k2上');
let k2 = await k1(); //await只能用在异步方法中
//获取 异步方法中的值
console.log(`3、k2:${k2}`);
return k2 //jojo
}
console.log('4、',k2());
console.log('5、00.0');
输出为
2、k2上
1、k1
4、 Promise { <pending> }
5、00.0
3、k2:JOJO
可以看到在一般await ssync函数中的执行过程为
//执行异步方法中的代码 遇到await停止 执行await后面的代码
//进入promise队列 等待非异步代码执行完毕 处理队列中的promise