2017-03-28 5 views
0

私は以前はうまくいくと思われていましたが、今はできません。ポーチを呼び出し中からコードに戻さないことを約束します

私はすべてのものが整っていると思いますが、.getが呼び出された後は決してforループには到達しません。

それは約束の終わりまで飛び、次に戻る(.get)の中に戻り、解決してから外に出ます。

エラーがあった場合は、キャッチにジャンプしていたはずですが、そうではありませんでした。どのようにforループが欠けていますか?ここで

コードです:

function readAllImagesFromPouch(id, imageDisplay) { 

     return new Promise(function (resolve, reject) { 

      var startElement = document.getElementById(imageDisplay); 
      var image = ""; 

      // Get all attachments for this id 

      DB_TaskImages.get(id, { attachments: true }).then(function (doc) { 

     for (var key in doc._attachments) { 

      DB_TaskImages.getAttachment(doc._id, key).then(function (blob) { 
       var img = document.createElement('img'); 
       blob = resizeImage(blob, "100", "60"); 
       var url = URL.createObjectURL(blob); 
       img.src = url; 
       //alert(img.outerHTML); 

       //startElement.appendChild(img); 
       $(startElement).append("<div class='row' style='border:1px solid black'><div class='col-xs-10'>" + 
          img.outerHTML + 
          "</div>" + 
          "<div class='col-xs-1' style='padding-top:20px'>" + 
          "<img src='../Images/delete.png' alt='Delete' class='taskimage'>" + 
          "</div></div>" 
         ); 
       return; 
      }).catch(function() { 
       console.log("No attachment for doc._id: " + doc._id + " and key: " + key); 
      }) 
     } 
     return; 
      }).then(function() { 
      resolve(); 
      }).catch(function (err) { 
     console.log("Image not there for id: " + id); 
     showMsg("Image not there for id: " + id); 
     reject(err); 
      }) 
     });   // end of promise 
    } 

そしてそれは、このコードから呼び出されます。まず

readAllImagesFromPouch("006", "divImages").then(function() { 
    }).catch(function (err) { 
     console.log("In catch for readAllImagesFromPouch with err: " + err); 
    }) 

おかげで、

トム

+0

問題が見つかりました。それはforループのエラーと関係していました。それはdoc.attachmentsだったはずです(なぜポーチドキュメントにアンダースコアを付けていたのかはわかりません - 私がそれを保存した方法かもしれません)。私の約束が正しければ私は好奇心が強いでしょう、そして私は正しい場所にすべての返品、解決、拒絶を持っています。まだこれを手に入れようとしています。 – tshad

+0

いいえ、あなたはまだPromiseコンストラクタをanti-patternにしておき、 'for ... in'ループ内のすべてのコードは、約束が解決された後に実行されます。あなたの' $(startElement).append'は、 –

+0

['Promise'コンストラクタの反パターンを避けてください](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi

答えて

0

は、約束のコンストラクタ抗を避けますパターン。 DB_TaskImages.getは約束を返すと、あなたは第二1

を作成する必要はありません、あなたのfor...inループは非同期タスクの束をキックオフ - しかし、彼らは

の可能な書き換えを完了させるためにあなたが実際に待っていませんあなたのコードは

function readAllImagesFromPouch(id, imageDisplay) { 

    var startElement = document.getElementById(imageDisplay); 
    var image = ""; 

    // Get all attachments for this id 

    return DB_TaskImages.get(id, { 
     attachments: true 
    }) 
    .then(function(doc) { 
     // a promise to chain to - all following tasks will be performed in series, not parallel - this can be changed 
     var promise = Promise.resolve(); 
     Object.keys(doc._attachments).forEach(function(key) { 
      promise = promise.then(function() { 
       return DB_TaskImages.getAttachment(doc._id, key) 
       .then(function(blob) { 
        var img = document.createElement('img'); 
        blob = resizeImage(blob, "100", "60"); 
        var url = URL.createObjectURL(blob); 
        img.src = url; 
        //alert(img.outerHTML); 

        //startElement.appendChild(img); 
        $(startElement).append("<div class='row' style='border:1px solid black'><div class='col-xs-10'>" + 
              img.outerHTML + 
              "</div>" + 
              "<div class='col-xs-1' style='padding-top:20px'>" + 
              "<img src='../Images/delete.png' alt='Delete' class='taskimage'>" + 
              "</div></div>" 
             ); 
        return; 
       }) 
       .catch(function() { 
        console.log("No attachment for doc._id: " + doc._id + " and key: " + key); 
       }) 
      }); 
     }); 
     return promise; 
    }) 
    .catch(function(err) { 
     console.log("Image not there for id: " + id); 
     showMsg("Image not there for id: " + id); 
     throw err; 
    }) 
} 

です。上記のコードでは、DB_TaskImages.getAttachment(doc._id, key)が連続して呼び出されます。

することができますし、並行してDB_TaskImages.getAttachment(doc._id, key)を実行する場合、コードはもう少し作業が必要

function readAllImagesFromPouch(id, imageDisplay) { 

    var startElement = document.getElementById(imageDisplay); 
    var image = ""; 

    // Get all attachments for this id 

    return DB_TaskImages.get(id, { 
     attachments: true 
    }) 
    .then(function(doc) { 
     return Promise.all(Object.keys(doc._attachments) 
      .map(function(key) { 
       return DB_TaskImages.getAttachment(doc._id, key) 
       // an error here should NOT reject the Promise.all, so handle the error and return undefined 
       .catch(function() { 
        console.log("No attachment for doc._id: " + doc._id + " and key: " + key); 
       }) 
      }) 
     ); 
    }) 
    .then(function(blobs) { 
     return blobs.filter(function(blob) { 
      // a failed .getAttachment results in an undefined result here, so ignore it 
      return blob !== undefined; 
     }).forEach(function(blob) { 
      var img = document.createElement('img'); 
      blob = resizeImage(blob, "100", "60"); 
      var url = URL.createObjectURL(blob); 
      img.src = url; 
      $(startElement).append(
       "<div class='row' style='border:1px solid black'>" + 
        "<div class='col-xs-10'>" + 
         img.outerHTML + 
        "</div>" + 
        "<div class='col-xs-1' style='padding-top:20px'>" + 
         "<img src='../Images/delete.png' alt='Delete' class='taskimage'>" + 
        "</div>" + 
       "</div>" 
      ); 
     }); 
    }) 
    .catch(function(err) { 
     console.log("Image not there for id: " + id); 
     showMsg("Image not there for id: " + id); 
     throw err; 
    }) 
} 
+0

'for(let key ...)またはIIFE – Bergi

+0

' Object.keys(doc._attachments).forEach(function(key){'の代わりに –

+0

@JaromandaX:あなたのシリーズの例を見ています私は、各画像のgetAttachmentからエラーが出ていますが、私は何かを見逃し、それを遊んでいると仮定します。あなたは毎日何か新しいことを学びます:)ありがとう、 – tshad

0

これは、これを行うには正しい方法ではないかもしれないが、私は私が見るように変更コードを表示したいですこれを行う正しい方法であれば。これは本当に@jaromandaXが答えた他の質問の一部です。

これは本当に同じ質問です - 約束を約束する方法

あなたのコードを見ると、blobが本当にblobではなかったため、resizeImageコードに問題がありました。私は他の例でblobutilを使用しなければならないと考えました。これは、本当にこのようにする必要がある場合、これを約束でどのように処理するかという問題です。

私の古いコードはでした:

function resizeImageOld(blob, maxWidth, maxHeight) { 
    // Set img src to ObjectURL 
    var showImage = document.createElement('img'); 
    var url = URL.createObjectURL(blob); 
    showImage.src = url; 

    var newImage; 

    showImage.onload = function() { 
     URL.revokeObjectURL(showImage.src); 
     var canvas = document.createElement("canvas"); 
     var ctx = canvas.getContext("2d"); 

     var MAX_WIDTH = maxWidth, maxHeight; 
     var MAX_HEIGHT = 60; 
     var width = showImage.width; 
     var height = showImage.height; 

     if (width > height) { 
    if (width > MAX_WIDTH) { 
     height *= MAX_WIDTH/width; 
     width = MAX_WIDTH; 
    } 
     } else { 
    if (height > MAX_HEIGHT) { 
     width *= MAX_HEIGHT/height; 
     height = MAX_HEIGHT; 
    } 
     } 

     canvas.width = width; 
     canvas.height = height; 

     ctx.drawImage(showImage, 0, 0, width, height); 
     newImage = canvas.toDataURL("image/png"); 
    } 
    return newImage; 
} 

それは約束がブロブリサイズ、それは別の画像を取り扱う前に、DOMに追加を取得する方法でし作ります。このようにして、onloadイベントは実行されませんでした。

私はそれを変更する:私は、今、次のようにこの約束を呼び出すコードを変更し、これはそれを処理するための正しい方法だったか、それだけの飛び出すでしょうかどうかを確認したかった

function resizeImage(blob, maxWidth, maxHeight) { 
    // Set img src to ObjectURL 

    return new Promise(function (resolve, reject) { 

     var showImage = document.createElement('img'); 
     var url = URL.createObjectURL(blob); 
     var newImage; 

     showImage.onload = function() { 
    URL.revokeObjectURL(showImage.src); 
    var canvas = document.createElement("canvas"); 
    var ctx = canvas.getContext("2d"); 

    var MAX_WIDTH = maxWidth, maxHeight; 
    var MAX_HEIGHT = 60; 
    var width = showImage.width; 
    var height = showImage.height; 

    if (width > height) { 
     if (width > MAX_WIDTH) { 
      height *= MAX_WIDTH/width; 
      width = MAX_WIDTH; 
     } 
    } else { 
     if (height > MAX_HEIGHT) { 
      width *= MAX_HEIGHT/height; 
      height = MAX_HEIGHT; 
     } 
    } 

    canvas.width = width; 
    canvas.height = height; 

    ctx.drawImage(showImage, 0, 0, width, height); 
    newImage = canvas.toDataURL("image/png"); 

    resolve(newImage); 
     } 

     showImage.src = url; 
    }) 
} 

その約束を守り続けると、それが他のイメージを通過した後に後で戻ってくる。それは良く見えますが、わかりません。

あなたのコード:

function readAllImagesFromPouch(id, imageDisplay) { 

    var startElement = document.getElementById(imageDisplay); 
    var img = ""; 
    var imgBlob; 
    var base64str; 
    var fileName; 

    ClearImagePanel(); 

    // Get all attachments for this id 

    return DB_TaskImages.get(id, { attachments: true }).then(function (doc) { 

     // a promise to chain to - all following tasks will be performed in series, not parallel - this can be changed 

     var promise = Promise.resolve(); 

     Object.keys(doc._attachments).forEach(function (key) { 
    promise = promise.then(function() { 
     return DB_TaskImages.getAttachment(doc._id, key).then(function (blob) { 

      img = document.createElement('img'); 

      return resizeImage(blob, "100", "60").then(function(blob) { 
      var url = URL.createObjectURL(blob); 

      img.src = myUrl; 
      $(startElement).append(img.outerHTML); 

      }) 
     }).catch(function (err) { 
      alert("No attachment for doc._id: " + doc._id + " and key: " + key); 
     }) 
    }); 
     }); 
     return promise; 
    }).catch(function (err) { 
     console.log("Image not there for id: " + id); 
     showMsg("Image not there for id: " + id); 
     throw err; 
    }) 
} 

はこの権利ですか、それはあなたが前に述べたアンチパターンの同じタイプのですか?

他にも2つの質問がありました。チェーン(この場合はDB_TaskImages.getAttachment、)の最初の約束を

  1. は、私たちは「それから」以下に戻ってきているので、我々は「リターン」を行うのですか?最初の約束が戻ってこなかった場合のリターンなどの例を見ていたので、わからなかった。

  2. 私の例では、 "return resizeImage"約束のために、私の後に.thenとcatchの後が必要ですか?私は、あなたが「約束を返す」ことをした後には、それ以上のことはしなかったが、それがあることに気づいた。

ちょっと好奇心。

ありがとうございました。

関連する問題