promise+await解決js中異步任務(wù)返回值的問(wèn)題


1. 問(wèn)題場(chǎng)景

完成一個(gè)簡(jiǎn)單的登錄注冊(cè)功能着憨。前端react+后臺(tái)koa2+MySQL數(shù)據(jù)庫(kù)。因?yàn)榈卿浐妥?cè)的業(yè)務(wù)流程差不多臼勉,我就拿登錄舉一個(gè)例子快毛。用戶輸入username和password,將這兩個(gè)參數(shù)通過(guò)get的方式傳遞給后臺(tái)捏雌,后臺(tái)使用router.get方式接受這兩個(gè)參數(shù)跃赚,再查詢數(shù)據(jù)庫(kù)中是否有該用戶相關(guān)信息,有的話返回前臺(tái)登錄成功性湿,沒(méi)有返回前臺(tái)登陸失敗纬傲。

2. 出現(xiàn)問(wèn)題

數(shù)據(jù)庫(kù)查詢connection.query()是異步的。我想要根據(jù)不同的查詢結(jié)果向前臺(tái)返回不同的響應(yīng)肤频,但是因?yàn)楫惒饺蝿?wù)調(diào)皮的特點(diǎn)叹括,還沒(méi)有等到查詢結(jié)果就會(huì)給前臺(tái)返回響應(yīng)(不寫(xiě)響應(yīng)還會(huì)404,就很離譜O摹)
問(wèn)題代碼類似于這樣(原來(lái)的忘了)

module.exports = ctx=>{
  var mysql = require('mysql');
  var connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'wxb7e2f16d9e113148',
    database: 'yhytest'
  });
  connection.connect();
  var a='ini';
  var sql = 'SELECT * FROM yhytesttable';
  //查詢數(shù)據(jù)庫(kù)
  connection.query(sql, function (err, result) {
    if (err) {
      a = err.message;
      return;
    }
    a = result["0"].name;
  });
  ctx.state.data = {
    msg: a
  }
}

為了解決這個(gè)問(wèn)題引出promise和await

3. promise

promise類似于一個(gè)容器汁雷,里面裝著一個(gè)異步任務(wù)净嘀,利用promise可以獲取異步任務(wù)的信息。

new Promise((resolve,reject)=>{
  // 里面是一個(gè)異步任務(wù)
  resolve()摔竿;// 異步任務(wù)成功了進(jìn)行它
  reject()面粮;// 異步任務(wù)失敗了進(jìn)行它
});

Promise的構(gòu)造函數(shù)里直接傳入了一個(gè)function,我們可以稱呼它為executor继低,它有兩個(gè)函數(shù)參數(shù)resolve熬苍,reject。當(dāng)上面這行語(yǔ)句執(zhí)行的時(shí)候袁翁,executor會(huì)立即異步執(zhí)行柴底。在executor方法的方法體內(nèi),你可以寫(xiě)你自己的代碼邏輯粱胜,你可以在代碼的正常執(zhí)行邏輯里調(diào)用resolve(retValue)來(lái)把Promise的status改為resolved柄驻,表示任務(wù)執(zhí)行成功;在出錯(cuò)異常處理的代碼里調(diào)用reject(err)來(lái)把Promise的status改為rejected焙压,表示任務(wù)執(zhí)行失敗鸿脓。也就是說(shuō),executor函數(shù)的執(zhí)行成功還是失敗涯曲,是可以從Promise的狀態(tài)里判斷出來(lái)的野哭。這里要注意兩點(diǎn):

  • Promise從pending狀態(tài)改為resolved或rejected狀態(tài)只會(huì)有一次,一旦變成resolve或rejected之后幻件,這個(gè)Promise的狀態(tài)就再也不會(huì)改變了拨黔。
  • 通過(guò)resolve(retValue)傳入的retValue可以是任何值,null也可以绰沥,它會(huì)傳遞給后面的then方法里的function去使用篱蝇。通過(guò)rejected(err)傳入的err理論上也是沒(méi)有限制類型的,但我們一般都會(huì)傳入一個(gè)Error徽曲,比如reject(new Error(“Error”))零截。promise的狀態(tài)可以影響后面then的執(zhí)行。
new Promise((resolve,reject)=>{
  resolve(value);
  reject(error);
}).then((value)=>{
  return 一個(gè)promise實(shí)例秃臣;
})

內(nèi)容參考:淺析JS中的 promise+await/async

4. async/await

async/await使得異步代碼看起來(lái)像同步代碼瞻润,但是改變不了JS單線程、異步的本質(zhì)甜刻。await就是等一等嗎绍撞,等等await后面的異步任務(wù)執(zhí)行完成之后,再進(jìn)行它之后的代碼的運(yùn)行得院。
用法:

  • 使用await傻铣,函數(shù)必須用async標(biāo)識(shí)
  • await后面跟的是一個(gè)Promise實(shí)例
// user.js
function userLogin(name, password) {
  // 處理異步任務(wù)返回的results
  return new Promise((resolve, reject) => {});
}
// index.js
router.get("/login", async (req, res) => {
  var name = req.query.userName;
  var pwd = req.query.userPwd;
  // await處理異步任務(wù)results,根據(jù)不同results情況向前臺(tái)返回不同響應(yīng)
  let results = await userLogin(name, pwd);
  if (results.length == 1) {
    req.body = "登陸成功祥绞!";
  } else {
    req.body = "登陸失敺侵蕖鸭限!請(qǐng)重新登陸!";
  }
});

index.js中的await就會(huì)讓userLogin執(zhí)行两踏,而不是不等執(zhí)行直接進(jìn)行req.body

內(nèi)容參考:異步解決方案----Promise與Await
先寫(xiě)到這败京,想起來(lái)別的了繼續(xù)寫(xiě)...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市梦染,隨后出現(xiàn)的幾起案子赡麦,更是在濱河造成了極大的恐慌,老刑警劉巖帕识,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泛粹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肮疗,警方通過(guò)查閱死者的電腦和手機(jī)晶姊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)伪货,“玉大人们衙,你說(shuō)我怎么就攤上這事〖詈簦” “怎么了蒙挑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)巍举。 經(jīng)常有香客問(wèn)我,道長(zhǎng)凝垛,這世上最難降的妖魔是什么懊悯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮梦皮,結(jié)果婚禮上炭分,老公的妹妹穿的比我還像新娘。我一直安慰自己剑肯,他們只是感情好捧毛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著让网,像睡著了一般呀忧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上溃睹,一...
    開(kāi)封第一講書(shū)人閱讀 49,772評(píng)論 1 290
  • 那天而账,我揣著相機(jī)與錄音,去河邊找鬼因篇。 笑死泞辐,一個(gè)胖子當(dāng)著我的面吹牛笔横,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播咐吼,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吹缔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了锯茄?” 一聲冷哼從身側(cè)響起厢塘,我...
    開(kāi)封第一講書(shū)人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撇吞,沒(méi)想到半個(gè)月后俗冻,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牍颈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年迄薄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片煮岁。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讥蔽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出画机,到底是詐尸還是另有隱情冶伞,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布步氏,位于F島的核電站响禽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏荚醒。R本人自食惡果不足惜芋类,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望界阁。 院中可真熱鬧侯繁,春花似錦、人聲如沸泡躯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)较剃。三九已至咕别,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間写穴,已是汗流浹背顷级。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留确垫,地道東北人弓颈。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓帽芽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親翔冀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子导街,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348