亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 課堂 > 小程序 > 正文

小程序異步問題之多個網絡請求依次執行并依次收集請求結果

2020-03-21 15:57:58
字體:
來源:轉載
供稿:網友

業務邏輯

最近開發一個便簽小程序的時候,有這樣一個需求:用戶可以在寫便簽的時候添加一個或多個圖片。

對于這個需求,我們用戶按下保存鍵時,內部具體的實現上是這樣的邏輯:

  1. 首先檢測用戶是否傳入了圖片,如果存儲本地圖片地址的數組長度>=1,則將圖片數組放入上傳圖片的函數。
  2. 由于小程序網絡請求大小限制,我們只能采取循環上傳單文件,然后收集每次請求的結果--圖片在服務器的地址,最后將結果放在一個數組中供后續的操作使用。
  3. 當圖片上傳函數全部執行完畢后,將數組中的圖片數組取出來,賦值到日記對象中,再將整個日記對象提交到服務器。
  4. 服務器返回保存成功或失敗。

思路其實非常清晰簡單,但是在代碼實現上卻翻了大跟頭。

異步帶來的問題

小程序的網絡請求是異步的:我們無法通過return來將網絡請求結果返回出來使用。

  wx.request({     //...省略其他屬性     success: function (res) {     },     fail: function (res) {     }  })

例如在微信中發送網絡請求,我們只能使用微信提供的方法wx.xxx,其中請求的結果保存在res中,而res無法直接return得到。

解決:res雖然無法直接獲取,但是我們能通過將需要使用到這個請求結果的業務邏輯代碼放入這個網絡請求的回調函數中直接讀取網絡請求結果,也就是一切都需要通過回調來解決。

  wx.request({     //...省略其他屬性     success: function (res) {      console.log(res);      //接業務邏輯代碼     },     fail: function (res) {      console.log(res);     }  })

例如這個微信的網絡請求,我們可以通過success和fail的回調函數來讀取res的值從而完成依賴res結果的業務邏輯。

回調地獄

雖然解決了結果獲取的問題,但是又產生了另一個問題,當多個請求中有明確的先后順序時,回調會嵌套的很厲害,造成回調地獄,代碼可讀性和可維護性都會很差。

例如對于一個日記頁面,需要先請求到頁面的數據(里面包含了圖片數據和其他數據的地址),再根據頁面數據去請求圖片數據后再請求音頻數據。例如以下代碼:

  //請求頁面整體數據  wx.request({     //...省略其他屬性     success: function (res) {//成功        //請求圖片數據        wx.request({         success: function (res) {//成功           //請求音頻數據           wx.request({             success: function (res) {//成功             },             fail: function (res) {//失敗               console.log("請求失敗:"+res);             }           })         },         fail: function (res) {//失敗           console.log("請求失敗:"+res);         }        })     },     fail: function (res) {//失敗       console.log("請求失敗:"+res);     }  })

如何優化?幸運的是,在es6里面我們可以用promise去優化我們的回調,用then代替回調,首先將網絡請求封裝成一個Promise:

// 后臺post請求  function postRequest(posturl, postdata) {   return new Promise((resolve, reject) => {    wx.request({     //省略其他屬性     success: function (res) {      console.log("at post request: 請求成功")      resolve(res.data)//設置promise成功標志     },     fail: function (res) {      console.log("at post request: 請求失敗")      reject(res.data)//設置promise失敗標志     }    })   });  }

這樣封裝以后,我們的網絡請求會在success和fail后回調resolve,這樣可以告訴promise,“hey,我完成我的工作了,你可以進行你的then操作了”,這樣就可以用then來簡化嵌套邏輯。使用promise來完成上面那個問題的請求將會是這樣的:

 postRequest(posturl,postdata)  .then(function(res){   //業務邏輯   //調用下一個請求   return postRequest(next_posturl,next_postdata);  })  .then(function(res){   //業務邏輯   //調用下一個請求   return postRequest(next_next_posturl,next_next_postdata);  })  .then(function(res){   //業務邏輯  });

是不是簡潔的多~

一個看似簡單的需求

我們的有一個很簡單的需求是需要對一組數量不定的圖片做分別上傳(因為微信限制所以無法做多上傳),并且在上傳完成以后需要獲取到所有的返回結果。

那么用我們前面的回調函數+then的話,很自然的想到這樣的寫法

postRequest(posturl,postdata).then(function(res){  //獲取返回res  //上傳下一個圖片  return postRequest(next_posturl,next_postdata);}).then(function(res){  //獲取返回res  //上傳下一個圖片  return postRequest(next_next_posturl,next_next_postdata);}).then(function(res){  //獲取返回res});

這樣看起來很簡單明了,但是我的圖片數量是不定的,怎么動態的構建.then.then.then這樣的鏈式調用呢?經過我的研究后發現可以通過一個輔助的promise鏈去完成主鏈的鏈式構建。

//多文件上傳function jabingp_upLoad(uploadurl, files) { return new Promise((resolve, reject) => {  //初始化promise鏈  var mergedAjax = Promise.resolve();  var response = [];  // 循環上傳    // 這里一定要使用let來為沒一次循環構建一個塊級作用域  // 使用var則需要配合立即執行函數  for (let i = 0; i < files.length; i++) {   mergedAjax = mergedAjax.then(() => {    return jabingp_upLoadSingle(uploadurl, files[i]).then((res) => {     response.push(res);    });   });  }  //當前面循環中所有的then執行完畢時會執行這個then  mergedAjax.then(() => {   resolve(response);      //設置這個函數的promise對象為完成狀態并放入數據  }); });}

通過這個函數,就完成了多個請求依次執行并收集結果的效果。這個函數的重點在于利用另外一個已經處于完成狀態的promise,不斷的迭代自身,在每次迭代的then內部通過return來完成輔助鏈到業務鏈的切換。

2019-04-27 更新

使用await/async更加優雅地處理異步吧!

在es7標準中,引入了await和async這對兄弟,它們可以讓我們的異步代碼看起來和同步代碼一樣。讓我們來看看await和async都能做什么吧。

await可以等待一個promise運行到完成狀態并且獲取結果,或者等待一個async修飾的函數運行完成并獲取結果,但是使用await的時候,必須在async函數體內部。比如我有這樣一個網絡請求:

 function postRequest(posturl, postdata) {   return new Promise((resolve, reject) => {    wx.request({     //省略其他屬性     success: function (res) {      console.log("at post request: 請求成功")      resolve(res.data)//設置promise成功標志     },     fail: function (res) {      console.log("at post request: 請求失敗")      reject(res.data)//設置promise失敗標志     }    })   });  }

那么如果不使用await,我就需要這樣取得請求結果

function test(){ postRequest(xxx,xxx).then(function(res){   // 這里面可以讀取請求結果res了   console.log(res); });}test();

可以看到,這樣的代碼不太符合常規邏輯,我們希望函數作用是返回數據,這樣更清晰明了,有了await,我們的愿望就可以實現了。

async function test(){ let res = await postRequest(xxx,xxx); // 下面就可以正常寫對res的讀取了 console.log(res);}test();

注意我給函數加上了async,有了async和await,我們就可以像同步代碼一樣使用異步請求了~

那么上面那個通過復雜的構建鏈完成的需求,通過await實現將會變得非常簡單易懂。

async function jabingp_upLoad(uploadurl, files) {  let response = [];   // 循環依次等待上傳結果  for (let i = 0; i < files.length; i++) {    let res = await jabingp_upLoadSingle(uploadurl, files[i]);    // 結果放入數組    response.push(res);  }  // 返回結果  return response ;}

代碼一下子變得簡潔易懂了,注意調用的時候也同樣需要在一個async函數內部執行await。

async function test(){ let response = await jabingp_upLoad(xxx,xxx); console.log(response );}test();

是不是非常簡單呢,趕緊在你的異步請求中使用async和await吧~

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩精品电影| 亚洲精品视频中文字幕| 欧美韩日一区二区| 欧美夫妻性生活视频| 亚洲国产99精品国自产| 日韩精品免费视频| 国产福利精品视频| 2020欧美日韩在线视频| 国产精品欧美一区二区| 中文字幕欧美日韩在线| 4438全国亚洲精品在线观看视频| 亚洲精品成人久久久| 在线视频欧美日韩精品| 亚洲级视频在线观看免费1级| 久久久爽爽爽美女图片| 狠狠色狠狠色综合日日小说| 性欧美办公室18xxxxhd| 日韩av片免费在线观看| 欧美黄色免费网站| 亚洲美女喷白浆| 日韩www在线| 国产精品18久久久久久首页狼| 国产精品免费视频xxxx| 九九热视频这里只有精品| 国模精品一区二区三区色天香| 久久久精品影院| 欧美最近摘花xxxx摘花| 色综合导航网站| 欧美成人午夜激情| 国产不卡视频在线| 91在线国产电影| 亚洲美女av在线播放| www国产亚洲精品久久网站| 亚洲精品在线不卡| 亲子乱一区二区三区电影| 国产精品美女久久久久av超清| 亚洲成人三级在线| 欧美精品精品精品精品免费| 久久久91精品国产一区不卡| 久久久久久久久中文字幕| 午夜伦理精品一区| 亚洲第一精品福利| 久久国产精彩视频| 黄色成人在线免费| 日韩高清不卡av| 91九色在线视频| 亚洲色图欧美制服丝袜另类第一页| 精品成人国产在线观看男人呻吟| 黑人巨大精品欧美一区二区三区| 北条麻妃一区二区三区中文字幕| 国产精品亚洲综合天堂夜夜| 精品久久久久久亚洲国产300| www日韩欧美| 国产成人精品一区二区| 亚洲美女精品久久| 亚洲综合精品伊人久久| 亚洲字幕一区二区| 亚洲成人国产精品| 欧美日韩国产第一页| 久久久精品久久久久| 91亚洲精品久久久久久久久久久久| 一本色道久久88综合亚洲精品ⅰ| 久久久最新网址| 久久精品99久久久香蕉| 91深夜福利视频| 亚洲无线码在线一区观看| 亚洲日韩中文字幕在线播放| 国产精品热视频| 国产日本欧美一区| 精品视频在线播放| 国产69精品久久久久99| 麻豆国产va免费精品高清在线| 久久久久久中文字幕| 这里只有精品在线观看| 中文字幕精品网| 55夜色66夜色国产精品视频| 正在播放欧美视频| 亚洲欧洲一区二区三区在线观看| 91精品国产精品| 国产网站欧美日韩免费精品在线观看| 欧美日韩国产精品一区二区不卡中文| 2019日本中文字幕| 日韩av黄色在线观看| 国产精品亚洲综合天堂夜夜| 久久久精品亚洲| 97人人模人人爽人人喊中文字| 久久久久久久久久久亚洲| 亚洲成人av在线| 麻豆国产va免费精品高清在线| 亚洲欧美精品一区| 亚洲网站在线观看| 北条麻妃99精品青青久久| 国产香蕉精品视频一区二区三区| 精品久久久免费| 日韩大片免费观看视频播放| 欧美综合一区第一页| 欧美激情精品久久久| 欧美大学生性色视频| 国产精品99久久久久久久久| 日本午夜在线亚洲.国产| 97香蕉久久夜色精品国产| 亚洲精品日韩激情在线电影| 欧美影院在线播放| 成人精品一区二区三区| 成人精品在线观看| 色一区av在线| 日韩av网站导航| 成人疯狂猛交xxx| 国产欧美精品一区二区| 国产69久久精品成人看| 精品视频在线播放免| 91精品久久久久久久久不口人| 国产精品久久一区主播| 热99精品只有里视频精品| 日韩av大片在线| 欧美限制级电影在线观看| 国产精品中文字幕在线观看| 日韩精品视频观看| 欧美激情综合色综合啪啪五月| 欧美日韩国产二区| 亚洲天堂一区二区三区| 日韩成人免费视频| 夜夜嗨av色一区二区不卡| 亚洲免费一级电影| 91色在线观看| 粉嫩av一区二区三区免费野| 日韩欧美精品免费在线| 69久久夜色精品国产7777| 亚洲国产精品999| 日韩中文字幕在线观看| 亚洲va欧美va国产综合久久| 国产精品吊钟奶在线| 奇门遁甲1982国语版免费观看高清| 国产精品久久久久久久久免费| 欧洲亚洲在线视频| 国产一区二区三区中文| 亚洲国产成人在线视频| 国产精品高潮呻吟久久av无限| 26uuu日韩精品一区二区| 欧美国产日本在线| 国产精品爱啪在线线免费观看| 欧美另类极品videosbestfree| 国产精品免费看久久久香蕉| 欧美激情一区二区三区高清视频| 全球成人中文在线| 日韩精品中文字| 97婷婷大伊香蕉精品视频| 久久五月天色综合| 亚洲视频在线观看| 久久影院中文字幕| 北条麻妃一区二区三区中文字幕| 日韩精品免费电影| 91在线播放国产| 欧美精品精品精品精品免费| 国产精品观看在线亚洲人成网| 日韩电影免费观看中文字幕| 亚洲欧美精品suv| 日韩欧美极品在线观看| 久久久999精品免费| 欧美国产欧美亚洲国产日韩mv天天看完整| 成人网在线视频| 久久亚洲电影天堂| 国产精品女人久久久久久| 欧美裸体xxxx|