プログラム画像合成:非同期同期同期同期同期ブロックレンダリング


物語が始まりました.プロシージャcanvas写真合成実機テストでは、エラーが報告されます.つまり、私は非同期的に50枚の画像を要求しています.各画像はgetImageInfoを通じて現地にダウンロードされ、canvasのキャンバスに描かれていますが、処理の過程でgetImageInfoは現地の画像を取得するエラーが発生します.つまり50枚を要求して、最後に描いたのは45枚か40枚しかないかもしれません.パケットロスよりもN倍重いです.
一連の調査を経て、原因は2つあるかもしれません.
1.画像要求のドメイン名は、必ず小さいプログラムでウィジェットを通して検証されていなければなりません(オーディエンスはドメイン名を変えてジャンプしてこのリスクを解決しました)
2.小プログラムの要求併発数が小プログラムの最大合併制限を超え、request、upladFile、downloadFileの最大合併制限は10個である.
開発者の経験:「コードの問題は、小プログラムが同時に10個のネットワーク要求しか送信できません.超過すればエラーが発生します.画像情報の取得もこの10個のネットワーク要求を占有します.画像情報を序列化したいです.同じ時間内に10個の要求を超えないようにコントロールしてください.1回に1つの要求だけを送信します.完了したら、次のステップに進みます.」
CNODEコミュニティの経験
原生promise、asyncはどうやって合併数を制御できますか?
1.ブルーバードは同時数量を制御することができます.
2.使う for 遍歴して、1回に2つを持ってきたり、複数を取り出したりします. また Promise.all その後 また await
3.promise.mapパッケージ
const promise=pmap(arr、async item=>{
      //
}、10)//最後はconcurrencyです.
4.倉庫を使いたくないです.https://github.com/sindresorh... 対応する方法、CTRL+C 来ますよ
ブルーバード同時制御数量…接触したことがありませんが、下の階はasyncとawaitだと思います.
ASyncとawaitを復習しに行きます.
asyncは何ですか?async関数宣言は非同期関数を定義し、この関数はAync Functionオブジェクトに戻ります.
async function name([param,[param[,...param]]]){

     statements

}
関数にはリセットのものがあります.async returnのものは何ですか?返したのはAyncFunctオブジェクトです.関数に含まれるコードを実行するという非同期関数を表しています.newのObjectまたは自分で書いた種類と同じです.new AryncFunct(arg 1[,arg 2],...argN])
awaitは何ですか
await操作子はPromiseオブジェクトを待つために使われます.これはasync関数だけで使われます.[rv]=await expression;
イメージを話してください.asyncは承諾をして、awaitは承諾を受けます.
asyncは何を約束しましたか?次の承諾関数、つまりPromiseです.
awaitは何を待っていますか?約束を待っています.つまりPromiseです.
function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}
async function asyncCall() {
  console.log('calling');
  var result = await resolveAfter2Seconds();
  console.log(result);
  // expected output: "resolved"
}
asyncCall();
 =>「caling」//瞬間印刷 =>「reolved」//二秒後に印刷
上のコードを下に分ける作業原理:
asyncCall実行
「caling」を印刷します
resoveAfter 2 Seconds()実行中、Promiseオブジェクト実行中
それと同時に、awaitはPromiseを受信する準備をしました.
2秒後、awaitはPromiseを受信し、reultに値を与えます.
「resoved」を印刷します
復習が終わったら、非同期制御の方法を試し始めます.
ネット友達のコードは片言だけで、本当に読めません.公式サイトPromise.mapを見に来てください.
Promise.map(
`    Iterable|Promise> input,
    function(any item, int index, int length) mapper,
    [Object {concurrency: int=Infinity} options]`
) -> Promise
`var promises = [];
for (var i = 0; i 
Map Option:concurrency
You may optionly specify a concurrency limit:
…map(…、{concurrency:3}
The concurrency limit aplies to Promises returned by the mapper function and it baically limits the number of Promises created.For example,if concurrency is 3 and the mapper calback hance berrement the carenteno further calbacks are careled until one of the pending Promises reolves.So the mapper function will be caled three times and it will be caled again only after at least one of the Promises loves.
ぼんやりしていて、読み終わっても使いません.
でも、いろいろと苦労して、やっと使うようになりました.Aray.prototype.mapとちょっと似ています.Promise.mapから入ってきたcalbackはAsync Functionで、つまりPromiseの関数に戻ります.
併発数の制御をしましたが、併発数を制御した後も写真データはまだ不完全です.10個同時、9個同時、5個同時、2個同時、全部試しました.全部だめです.非同期に変更しなければなりません.つまり、毎回1つしか要求できません.つまり、同時数を1つに設定すればいいです.しかし、ユーザーの体験は非常によくないです.ユーザーは1枚の写真しか見られません.60枚あると仮定して、1枚の要求が必要です.最後にもう1枚の完全な写真を合成します.
しかし、すべての画像をダウンロードできるようにするために、すべての画像を正常に表示することができます.
Promise.map(photoData, function (photo) {
  return getImageInfoPromisified({
    src: photo.url
  }).then(function (res) {
    imagesArr.push(res.path);
    picx = (photo.left / 2) * ratio;
    picy = ((photo.top - 360) / 2) * ratio;
    picwidth = ((photo.width / 2) - 4) * ratio;
    picheight = ((photo.height / 2) - 4) * ratio;
    ctx.drawImage(res.path, picx, picy, picwidth, picheight);
    ctx.draw(true);

  }).catch(function () {
    console.error("get location failed")
  });
}, { concurrency: 1}).then(function () {
  wx.canvasToTempFilePath({
    canvasId: 'pic',
    success: function (res) {
      console.log(res.tempFilePath)
      that.setData({
        onlineImage: res.tempFilePath,
        canvasDisplay: "none"
      })
    }
  })
});
この問題は最終的にはブルーバードのpromise.map方法を使って、併発要求数を制御して実現されたものであり、つまり「concurrency:1」ここでは、10個以下の同時処理が期待されていません.併発であれば、いずれもデータが失われることになります.
したがって、非同期同期同期ブロックレンダリングに変更することができます.
この問題の出現は、私たちの画像合成機能の設計アーキテクチャと大きな問題があります.実は、最も理想的な状況は、サービス端末が直接に大きな画像に戻り、フロントエンドは一回のネットワーク要求だけでいいです.
最後に非同期同時レンダリングを通じて同期ブロッキングレンダリングに転換し、すべての画像リソースを獲得しましたが、これは良い解決策ではないので、この文章は主に非同期同時並行数量制御の方法を説明しました.あとは、この機能を合成した画像の設計構造に関するいくつかの考えです.
That's it