需求:
三个步骤,后一个步骤进行需要依赖前一个步骤,这里抽象为三个函数,每个函数都包含异步操作。
方法包含promise.then串联以及async+await,下面分别进行介绍:
- promise.then
利用promise的then来解决nodejs存在的回调地狱问题,只需要不断的加then即可实现异步函数的串行执行
let promise = function(){
return new Promise((resolve, reject)=>{
/*******中间部分精简,可以看出下面是异步函数*******/
for(let i=0;i<files.length;i++){
if(fileName[1] === "shp"){
let shp2geojson = cp.spawn(config.pythonExePath, par2);
shp2geojson.on('exit', (code2) =>{
console.log(`shp2geojson进程使用代码 ${code2} 退出`);
if(code2!=0){
let msg={code:-1,message:'inp operation err!2'}
res.end(JSON.stringify(msg));
return
}
resolve(out2Path + 'promise1');//resolve 下一个then所需的数据
})
}
}
}).then((path)=>{
return new Promise((resolve, reject)=>{
console.log(path);
/*******中间部分精简,可以看出下面是异步函数*******/
fs.readdir(out2Path,(err, files)=>{
for(let i=0;i<files.length;i++){
let geojsonTrans = cp.spawn(config.pythonExePath, par3);
geojsonTrans.on('exit', (code3)=>{
console.log(`geojsonTrans进程使用代码 ${code3} 退出`);
if(code3!=0){
let msg={code:-1,message:'inp operation err!3'}
res.send(JSON.stringify(msg));
return
}
resolve(out3Path + 'promise3');//resolve 下一个then所需的数据
})
}
})
})
}).then((path)=>{
return new Promise((resolve, reject)=>{
console.log(path)
/*******中间部分精简,可以看出下面是异步函数*******/
fs.readdir(out3Path, (err, files) => {
fs.readdir(out3Path, (err,files)=>{
//将数据传回前台
let obj = {
"type": "FeatureCollection",
"features":undefined
};
obj.features = resJSONObj;
res.send({code:0, message:'suc', data:obj});//返回前台的数据
})
});
})
}).catch((err)=>{
console.log(err);
}).finally((fin)=>{
console.log(fin);
})
}
promise();
- async await
async函数与await结合,即可实现串行执行函数,实现异步变同步的效果,这样比promise不断的then更加简洁,明了
//函数1
function shpToGeo(){
return new Promise((resolve, reject)=>{
for(let i=0;i<files.length;i++){
//匹配shp,循环调用转换函数
if(fileName[1] === "shp"){
/*******中间部分精简,可以看出下面是异步函数*******/
let shp2geojson = cp.spawn(config.pythonExePath, par2);
shp2geojson.on('exit', (code2) =>{
console.log(`shp2geojson进程使用代码 ${code2} 退出`);
if(code2!=0){
let msg={code:-1,message:'inp operation err!2'}
res.end(JSON.stringify(msg));
return
}
resolve('func2');//resolve 函数2所需的数据
})
}
}
})
}
//函数2
function geoTransFuc(){
return new Promise((resolve, reject)=>{
/*******中间部分精简,可以看出下面是异步函数*******/
fs.readdir(out2Path,(err, files)=>{
for(let i=0;i<files.length;i++){
let geojsonTrans = cp.spawn(config.pythonExePath, par3);
geojsonTrans.on('exit', (code3)=>{
console.log(`geojsonTrans进程使用代码 ${code3} 退出`);
if(code3!=0){
let msg={code:-1,message:'inp operation err!3'}
res.send(JSON.stringify(msg));
return
}
resolve('fuc3');//resolve 函数3所需的数据
})
}
})
})
}
//函数3
function mergeFuc(){
return new Promise((resolve, reject)=>{
fs.readdir(out3Path, (err, files) => {
fs.readdir(out3Path, (err,files)=>{
let obj = {
"type": "FeatureCollection",
"features":undefined
};
obj.features = resJSONObj;
resolve(obj);//resolve 所需返回前台的数据
})
});
})
}
async function demo(){
let shp = await shpToGeo();
let geo = await geoTransFuc(shp);
let obj = await mergeFuc(geo);
//obj会成为then方法回调函数的参数
return obj;
}
demo().then((obj)=>{
console.log(obj);
res.send({code:0, message:'suc', data:obj});
})
需要注意await只能用在async函数内,await意为等待该函数执行完成,获取promise resolve的值之后,再进行下面的操作。
async函数会返回一个Promise对象,所以也可以使用then方法添加回调函数,这里我添加了一个回调函数,使得执行完成任务后,将结果返回前台