微信小プログラム踏坑シリーズ--wx.request非同期処理について

6645 ワード

原文リンク:www.xksblog.top/talk-about-… wx.requestの最初の目を見て、$.ajaxというものを思い出しました.確かに使いにくいことがたくさんあります.我慢できません.幸いなことに、小さなプログラムはES 6文法をサポートしているので、promiseを使って少し改造することができます.
まずwxについてお話しします.requestはどうして我慢できないのですか.
敷物:「見えるのに捕まえられない」という非同期リクエスト
Page({
  data: {
    myData: ''
  },
  // loadMyData      myData  
  loadMyData () {
    console.log('       :' + this.data.myData)
  },
  //       onload        
  onload: function () {
    wx.request({
      url: 'https://api',  //   api    
      success: res => {
        console.log(res.data)
        this.setData({
          myData: res.data
        })
        console.log(this.data.myData)
      }
    })
    //        
    this.loadMyData()
  }
})

コンソールで次のような結果になります.
これは実は簡単な非同期問題ですwx.requestは非同期リクエストで、JSはwxを待つことはありません.requestの実行が完了してから下へ実行するので、JSは順番にこれを先に実行する.loadMyData()は、サーバからデータが戻ってくると、loadMyData()はとっくに実行済みで、もちろん値は得られません.
実は私达は同期の流れの中でやっと“返します”を言って、非同期は“返します”のこの概念がなくて(あるいは非同期は意味がありません)、非同期は“コールバック”に対応して、つまり1つの非同期の関数に対して、私达は1つの“コールバックの関数”に入って结果を受信するべきです.
初歩的な解決:コールバックによる受信結果
最も簡単な解決策は、非同期データを使用する必要がある関数をコールバックに書くことです.
...
onload: function () {
  wx.request({
    url: 'https://api',  //   api    
    success: res => {
      console.log(res.data)
      this.setData({
        myData: res.data
      })
      console.log(this.data.myData)
      //               success 
      this.loadMyData()
    }
  })
}

これにより、正しく出力できます.
しかし、論理が複雑で、多層非同期操作が必要な場合、どのような状況になるのでしょうか.
asyncFn1(function(){
  //...
  asyncFn2(function(){
    //...
    asyncFn3(function(){
      //...
      asyncFn4(function(){
        //...
        asyncFn5(function(){
           //...
        });
      });
    });
  });
});

頭皮がしびれると感じましたか?何が優雅で何が可読なのか、一瞬にして消えてしまうのが恐怖の「コールバック地獄」(Callback Hell)だ.
私たちは、微信ウィジェットのネットワーク要求wxを発見しました.requestは、このようなコールバック関数に依存する形式であり、従来の$.ajaxと同様に、論理が複雑で、ページの実行順序が要求される場合、弊害も明らかである.しかし、小さなプログラムがES 6をサポートしているので、Promiseを思う存分抱擁することができます.
Promiseを使用してwxを包装する.request
Promiseというものは簡単に言えば、非同期の実行ロジックと結果処理を分離し、1層また1層のコールバックネストを捨てて、処理ロジックをより明確にすることができます.具体的に知りたいのは、自分で資料を探してください.
今すぐPromiseでwxを包装します.request:
/**
 * requestPromise   wx.request   Promise  
 * @param:{string} myUrl     
 * @return: Promise    
 */
const requestPromise = myUrl => {
  //     Promise    
  return new Promise((resolve, reject) => {
    wx.request({
      url: myUrl,
      success: res => resolve(res)
    })
  })
}
//          utils.js ,            
module.exports = requestPromise

今から使ってみます.
//     
const utilApi = require('../../utils/util.js')
Page({
  ...
  //       onload        
  onLoad: function () {
    utilApi.requestPromise("https://www.bilibili.com/index/ding.json")
    //   .then    
    .then(res => {
      console.log(res.data)
      this.setData({
        myData: res.data
      })
      console.log(this.data.myData)
      this.loadMyData()
    })
  }
})

結果はコールバック関数の使用と一致した.複数の非同期要求がある場合、直接継続する.then(fn)は処理すればよく,論理がはっきりしている.
もちろん、ここでは最も簡単なPromise関数を書いただけで、まだ完全ではありません.より完全なPromise化wx.request、後で業務を改善する必要があるでしょう.また,各種の小プログラム開発フレームワークにも既存のpromise化APIがあり,すぐに利用できる.
転載先:https://juejin.im/post/5bac8e866fb9a05cf23001fe