Javascript异步编程的四种方式
在javascript开发过程中,我们不可避免的会遇到一些异步编程的情景,无论是前端的ajax请求还是,node的各种异步api,下文是在工作学习过程中总结的关于javascript异步编程集中常见方式用法的总结
回调函数
使用回调函数是最常见的一种形式
//jQuery ajax
$.get('test.php',res=>{
//数据处理
});
//node异步读取文件
let fs=require('fs');
fs.read('file/path',(error,data)=>{
//数据处理
});
回调函数就是定义函数的时候,将另外一个函数(回调函数)作为参数传入,在异步操作执行完成后就会执行该回调函数,从而可以保证在回调函数中的操作可以在异步执行完成之后执行。回调函数的缺点是当需要执行多个异步操作时,需要将多个回调函数嵌套在一起,组成代码结构上的混乱,可读性较差,被称为“回调地狱”。
func1(data1,()=>{
func2(data2,()=>{
func3(data3,()=>{
//业务逻辑
});
});
});
Promise
Promise以一种链式调用的方法来组织异步代码,可以将原来以回调函数形式调用的异步操作,改写为promise链式调用
//jQuery ajax promise
$('test.html').then(res=>{
//业务逻辑
}).then(res=>{
//业务逻辑
});
我们还可以利用ES6的Promise构造函数,自定义Promise
let resultA=new Promise((resolve,reject)=>{
let flag=Math.random()<0.5;
setTimeout(()=>{
if(flag){
resolve({
result:true,
msg:'ok'
});
}
else{
reject({
result:false,
msg:'error'
});
}
},0);
});
resultA.then(res=>{
console.log(res.msg);
return Promise.resolve('I am from this first promise');
}).catch(err=>{
console.log(err.msg);
}).then(res=>{
console.log(res);
});
在最新版本的node(node 8.0+)环境里,还可以利用util.promisify方法将回调函数形式的函数直接转换为Promise形式。
let util = require('util');
let fs = require('fs');
let readFilePromise = util.promisify(fs.readFile);
readFilePromise('demo.js','utf-8').then((data)=>{
console.log(data);
});
Generators
node的著名开发者TJ利用ES6的新特性生成器开发了一个异步控制控制工具co,Generators生成器,借助co可以将异步代码的写法写成类似同步代码的形式。
let util = require('util');
let fs = require('fs');
let co=require('co');
let readFilePromise = util.promisify(fs.readFile);
co(function *(){
let baz = yield readFilePromise('baz.js','utf-8');
console.log(baz);
let foo = yield readFilePromise('foo.js','utf-8');
console.log(foo);
});
可以看出Generator的优点显而易见,它可以使异步代码写的非常清晰,可读性很高,缺点使依赖第三方库才能使用该特性。
Async/Await
node7.6以上的版本引入了一个es7的新特性 Async/Await,专门用来进行异步控制,下面先看一简单的个例子
let delay = new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log('test');
resolve('msg from promise');
});
});
let baz = async ()=>{
let res = await delay;
console.log(res);//'msg from promise'
};
baz();
首先我们需要使用async关键字定义一个包含异步代码执行的函数,在promise形式你的异步执行函数前面使用await关键字,就可以将异步写成同步的操作形式。
相比Generators生成器,由于Async/Await使原生的异步控制方案,所以比较推荐使用的。

浙公网安备 33010602011771号