鍍金池/ 問(wèn)答/HTML/ 關(guān)于async/await的疑問(wèn)

關(guān)于async/await的疑問(wèn)

希望等待一步操作完成之后,再往下執(zhí)行 為啥這個(gè)不行

async function f(mysql_con){
        await mysql_con.query("select * from stu_detail where stu_no = ?",['2015130'],async function(err,result,fields){
            console.log(result)
            console.log(q.sql)
            if(result.length == 0){
                console.log("數(shù)據(jù)為空");
                await mysql_con.query("insert into stu_detail set ?",{stu_no:"2015130"},function(err,result,fields){
                    console.log(a.sql)
                    if(err){
                        console.log(err)
                    }
                    console.log("charu")
                    console.log(result)
                    
                })
            
            }else{
                await  mysql_con.query("update stu_detail set ?",{stu_name:"陳翰軒"});
            }
        for(var i=0;i<fields.length;i++){
            // console.log(fields[i])
            console.log(fields[i].name)
        }
    
        // pools[0].end();
        // exitProcess()
    })
        mysql_con.end();
        exitProcess()
}
回答
編輯回答
鹿惑
await操作符期望后面的表達(dá)式是一個(gè)promise,如果不是promise,那么轉(zhuǎn)換為resovled promise,也就是通過(guò)Promise.resolve方法調(diào)用
function query(query,callback){
    setTimeout(function(){
        callback&&callback(query);
    },2000);
}

async function f(){
    await query("1",async function(result){
        console.log("query1:"+result);
        if(result==="1"){
            await query("2",async function(result){
                console.log("query2:"+result);
            });
        }else{
            await query();
        }
        console.log("~~~~end~~~~~");
    });
}
f();

輸出

query1:1
~~~~end~~~~~
query2:2

而不是期望的

query1:1
query2:2
~~~~end~~~~~

那么我們就需要改造下

function query(paremeter,callback){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            callback&&callback(paremeter);
            resolve();
        },2000);
    });

}

async function f(){
    await query("1",async function(result){
        console.log("query1:"+result);
        if(result==="1"){
            await query("2",async function(result){
                console.log("query2:"+result);
            });
        }else{
            await query();
        }
        console.log("~~~~end~~~~~");
    });
    
   
}
f();
console.log("oh yeah");

輸出:

oh yeah
query1:1
query2:2
~~~~end~~~~~

和期望的還是有出入:

query1:1
query2:2
~~~~end~~~~~
oh yeah

應(yīng)為f函數(shù)沒有await操作符修飾,是一個(gè)同步調(diào)用,所以 oh yeah將會(huì)被接下來(lái)馬上執(zhí)行
好!,添加 await 后執(zhí)行
輸出:

query1:1
oh yeah
query2:2
~~~~end~~~~~

還是不對(duì),這是因?yàn)榈?次query await 執(zhí)行完后query已經(jīng)得到了resolve的值了,f函數(shù)已經(jīng)執(zhí)行完畢了,下一語(yǔ)句就會(huì)被執(zhí)行,而不會(huì)等回調(diào)中的結(jié)果,除非

function query(paremeter,callback){
    return new Promise(function(resolve,reject){
        setTimeout(async function(){
            await callback(paremeter);
            resolve();
        },2000);
    });
}

async function f(){
    await query("1",async function(result){
        console.log("query1:"+result);
        if(result==="1"){
            await query("2",async function(result){
                console.log("query2:"+result);
            });
        }else{
            await query();
        }
        console.log("~~~~end~~~~~");
    });
    
   
}
await f();
console.log("oh yeah");

結(jié)果:

query1:1
query2:2
~~~~end~~~~~
oh yeah

其實(shí)既然使用到了await操作符,那么在接口設(shè)計(jì)的時(shí)候就需要就要避免再使用回調(diào)函數(shù)的處理方式,
可以改造如下:

function queryWithPromise(paremeter){
    return new Promise(function(resolve,reject){
        setTimeout(async function(){
            resolve(paremeter||"DEFAULT");
        },2000);
    });
}

async function f(){
    var result=await queryWithPromise("1");
    console.log("query1:"+result);
    if(result==="1"){
        result=await queryWithPromise("2");
        console.log("query2:"+result);
    }else{
        result=await queryWithPromise();
        console.log("default:"+result);
    }
    
    console.log("~~~~end~~~~~");
    return result;
   
}
var result=await f();
console.log("f result:"+result);
console.log("oh yeah");

結(jié)果:

query1:1
query2:2
~~~~end~~~~~
f result:2
oh yeah

和同步編程思維match

2017年1月19日 19:13
編輯回答
遲月

await 明顯不是這樣用的。

await function1

而不是
await function1(function (){
})

如果function1不是返回的Promise,那么你用await肯定沒效果

2017年6月6日 19:30
編輯回答
孤島

你這個(gè)顯然不能用async+await,要先promise化,你這個(gè)現(xiàn)在是用回調(diào)的形式

2017年5月6日 18:41
編輯回答
舊酒館

我使用了 bluebird 這個(gè)包

const bluebird = require('bluebird');

async function f(mysql_con){
    const query = bluebird.promisify(mysql_con.query.bind(mysql_con));
    const result1 = await query('XXX');
    const result2 = await query('XXX');
    console.log(result1,result2)
}
2018年8月27日 09:26