Node.js中使用mysql時(shí)報(bào)錯(cuò)Error: Cannot enqueue Query after invoking quit.的解決方法

Error: Cannot enqueue Query after invoking quit.
    at Protocol._validateEnqueue (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/protocol/Protocol.js:215:16)
    at Protocol._enqueue (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/protocol/Protocol.js:138:13)
    at Connection.query (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/Connection.js:201:25)
    at Query.<anonymous> (/Users/jabingp/Github/CodeSharing/dist/backEnd/db/DB.js:86:34)
    at Query.<anonymous> (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/Connection.js:525:10)
    at Query._callback (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/Connection.js:491:16)
    at Query.Sequence.end (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
    at Query._handleFinalResultPacket (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/protocol/sequences/Query.js:139:8)
    at Query.OkPacket (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/protocol/sequences/Query.js:72:10)
    at Protocol._parsePacket (/Users/jabingp/Github/CodeSharing/node_modules/mysql/lib/protocol/Protocol.js:291:23)

出錯(cuò)代碼如下

updateDatas(datas:Array<any>){
        this.connect();
        console.log("要修改的數(shù)據(jù):")
        console.log(datas);
        for(let data of datas){
            this.connection.query(`update test set name = "${data.name}" where id = ${data.id}`,(error, results) =>{
                if (error) throw error;
                console.log(results);
                this.connection.query('SELECT * from test', function (error, results, fields) {
                    if (error) throw error;
                    console.log("查詢結(jié)果是");
                    console.log(results);
                });
            });
        }
        this.end();
    }

這段代碼我想完成的事情是每次更新后都查詢所有的值沦偎,輸出一下每個(gè)值的當(dāng)前狀態(tài)搅吁,然后執(zhí)行完所有查詢就把數(shù)據(jù)庫(kù)關(guān)閉。

解決方案

從錯(cuò)誤中可以看出來(lái)大概是數(shù)據(jù)庫(kù)以及關(guān)閉了,但代碼卻執(zhí)行了數(shù)據(jù)庫(kù)操作御铃,我們把最下面的this.end()去掉,代碼就成功執(zhí)行了沈矿,或者在代碼運(yùn)行的其他階段執(zhí)行this.end()上真,避免數(shù)據(jù)庫(kù)連接關(guān)閉的情況下執(zhí)行數(shù)據(jù)庫(kù)查詢操作。
執(zhí)行結(jié)果

更改數(shù)據(jù)
要修改的數(shù)據(jù):
[ { name: 'change Hello World again', id: 4 },
  { name: 'change Hellow JabinGP again', id: 5 } ]
connected as id 285992
OkPacket {
  fieldCount: 0,
  affectedRows: 1,
  insertId: 0,
  serverStatus: 2,
  warningCount: 0,
  message: '(Rows matched: 1  Changed: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0 }
OkPacket {
  fieldCount: 0,
  affectedRows: 1,
  insertId: 0,
  serverStatus: 2,
  warningCount: 0,
  message: '(Rows matched: 1  Changed: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0 }
查詢結(jié)果是
[ RowDataPacket { id: 4, name: 'change Hello World again' },
  RowDataPacket { id: 5, name: 'change Hellow JabinGP again' } ]
查詢結(jié)果是
[ RowDataPacket { id: 4, name: 'change Hello World again' },
  RowDataPacket { id: 5, name: 'change Hellow JabinGP again' } ]

結(jié)果并不是預(yù)想的輸出一個(gè)插入結(jié)果后輸出一個(gè)查詢結(jié)果羹膳,而是兩個(gè)插入結(jié)果先輸出后輸出兩個(gè)查詢結(jié)果睡互,為什么?下面進(jìn)行個(gè)人的推測(cè)分析陵像。

原因分析

錯(cuò)誤分析

我在前面的文章http://www.reibang.com/p/59fda67a868e
提到過(guò)就珠,connection關(guān)閉時(shí)并不會(huì)直接關(guān)閉,而是會(huì)將任務(wù)隊(duì)列中的任務(wù)都執(zhí)行完才關(guān)閉醒颖,而回調(diào)是任務(wù)執(zhí)行成功或者失敗后調(diào)用的妻怎,關(guān)閉連接時(shí)的確會(huì)檢查任務(wù)隊(duì)列,但是回調(diào)函數(shù)不在任務(wù)隊(duì)列中泞歉,也就是說(shuō)回調(diào)函數(shù)里面的:

this.connection.query('SELECT * from test', function (error, results, fields) {
                    if (error) throw error;
                    console.log("查詢結(jié)果是");
                    console.log(results);
                });

這個(gè)部分不會(huì)被識(shí)別為任務(wù)隊(duì)列逼侦,所以系統(tǒng)并不會(huì)知道這個(gè)任務(wù)是要再關(guān)閉數(shù)據(jù)庫(kù)之前執(zhí)行的,系統(tǒng)僅僅只是確保了循環(huán)中的"insert xxx" 會(huì)在被關(guān)閉連接前執(zhí)行腰耙,但不保證回調(diào)中"select * xxx"會(huì)在關(guān)閉連接前執(zhí)行榛丢,于是在執(zhí)行這個(gè)語(yǔ)句之前數(shù)據(jù)庫(kù)連接就關(guān)閉了,導(dǎo)致報(bào)錯(cuò)挺庞。

結(jié)果為何不理想

由于for循環(huán)執(zhí)行極快(對(duì)比使用網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)庫(kù))晰赞,兩個(gè)插入操作幾乎是同時(shí)進(jìn)入任務(wù)隊(duì)列然后先后執(zhí)行,執(zhí)行兩個(gè)插入操作后此時(shí)任務(wù)隊(duì)列為空挠阁,不執(zhí)行任何數(shù)據(jù)庫(kù)操作宾肺,等待插入操作成功后,輸出完兩個(gè)的結(jié)果侵俗,代碼才執(zhí)行到查詢操作锨用,查詢操作才進(jìn)入任務(wù)隊(duì)列,隨后才回調(diào)輸出查詢結(jié)果隘谣,所以是兩個(gè)插入先依次輸出增拥,兩個(gè)查詢后依次輸出啄巧。

驗(yàn)證分析

因?yàn)閚ode中的mysql是異步的,但是有任務(wù)隊(duì)列機(jī)制掌栅,我們將查詢部分的代碼拉出回調(diào)秩仆,改為和插入并列,這樣由于隊(duì)列機(jī)制猾封,執(zhí)行上也是有先后順序的澄耍,所以能達(dá)到我想要的效果:

updateDatas(datas:Array<any>){
        this.connect();
        console.log("要修改的數(shù)據(jù):")
        console.log(datas);
        for(let data of datas){
            this.connection.query(`update test set name = "${data.name}" where id = ${data.id}`,(error, results) =>{
                if (error) throw error;
                console.log(results);
            });
            this.connection.query('SELECT * from test', (error, results, fields)=> {
                if (error) throw error;
                console.log("查詢結(jié)果是");
                console.log(results);
               
            });
        }
        this.end();
    }

執(zhí)行結(jié)果:

更改數(shù)據(jù)
要修改的數(shù)據(jù):
[ { name: 'change Hello World again', id: 4 },
  { name: 'change Hellow JabinGP again', id: 5 } ]
connected as id 285986
OkPacket {
  fieldCount: 0,
  affectedRows: 1,
  insertId: 0,
  serverStatus: 2,
  warningCount: 0,
  message: '(Rows matched: 1  Changed: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0 }
查詢結(jié)果是
[ RowDataPacket { id: 4, name: 'change Hello World again' },
  RowDataPacket { id: 5, name: 'change Hellow JabinGP again' } ]
OkPacket {
  fieldCount: 0,
  affectedRows: 1,
  insertId: 0,
  serverStatus: 2,
  warningCount: 0,
  message: '(Rows matched: 1  Changed: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0 }
查詢結(jié)果是
[ RowDataPacket { id: 4, name: 'change Hello World again' },
  RowDataPacket { id: 5, name: 'change Hellow JabinGP again' } ]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市晌缘,隨后出現(xiàn)的幾起案子齐莲,更是在濱河造成了極大的恐慌,老刑警劉巖磷箕,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件选酗,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岳枷,警方通過(guò)查閱死者的電腦和手機(jī)芒填,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)空繁,“玉大人殿衰,你說(shuō)我怎么就攤上這事〖已幔” “怎么了播玖?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵椎工,是天一觀的道長(zhǎng)饭于。 經(jīng)常有香客問(wèn)我,道長(zhǎng)维蒙,這世上最難降的妖魔是什么掰吕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮颅痊,結(jié)果婚禮上殖熟,老公的妹妹穿的比我還像新娘。我一直安慰自己斑响,他們只是感情好菱属,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著舰罚,像睡著了一般纽门。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上营罢,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天赏陵,我揣著相機(jī)與錄音,去河邊找鬼。 笑死蝙搔,一個(gè)胖子當(dāng)著我的面吹牛缕溉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吃型,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼证鸥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了勤晚?” 一聲冷哼從身側(cè)響起敌土,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎运翼,沒(méi)想到半個(gè)月后返干,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡血淌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年矩欠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悠夯。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡癌淮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沦补,到底是詐尸還是另有隱情乳蓄,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布夕膀,位于F島的核電站虚倒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏产舞。R本人自食惡果不足惜魂奥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望易猫。 院中可真熱鬧耻煤,春花似錦、人聲如沸准颓。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)攘已。三九已至炮赦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贯被,已是汗流浹背眼五。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工妆艘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人看幼。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓批旺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親诵姜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汽煮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常棚唆。 O...
    我想起個(gè)好名字閱讀 5,320評(píng)論 0 9
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,103評(píng)論 1 32
  • 今天看到一位朋友寫的mysql筆記總結(jié)暇赤,覺(jué)得寫的很詳細(xì)很用心,這里轉(zhuǎn)載一下宵凌,供大家參考下鞋囊,也希望大家能關(guān)注他原文地...
    信仰與初衷閱讀 4,734評(píng)論 0 30
  • 從哪說(shuō)起呢? 單純講多線程編程真的不知道從哪下嘴瞎惫。溜腐。 不如我直接引用一個(gè)最簡(jiǎn)單的問(wèn)題,以這個(gè)作為切入點(diǎn)好了 在ma...
    Mr_Baymax閱讀 2,762評(píng)論 1 17
  • 昨天和一個(gè)朋友聊天瓜喇,不知不覺(jué)的聊到時(shí)間挺益。說(shuō)這一年又快過(guò)去了。我對(duì)時(shí)間向來(lái)敏感乘寒,特別是一到暑假望众,我就感覺(jué)這一年又要過(guò)...
    小藍(lán)兒閱讀 177評(píng)論 0 0