nodejs异步函数串行执行(promise async+await)

本文介绍了如何使用Promise.then和async/await解决Node.js中的回调地狱问题,通过示例展示了如何实现异步函数的串行执行。Promise.then通过链式调用来确保步骤间的依赖,而async/await提供了更简洁的语法,使得异步代码看起来更接近同步。两种方法都有其优势,但async/await通常被认为更易读和维护。
摘要由CSDN通过智能技术生成
需求:
三个步骤,后一个步骤进行需要依赖前一个步骤,这里抽象为三个函数,每个函数都包含异步操作。
方法包含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方法添加回调函数,这里我添加了一个回调函数,使得执行完成任务后,将结果返回前台

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值