0

私はAngular2を使ってアプリケーションを構築しています。 Amazon S3にMultipartのアップロードをしようとしています。オブジェクトを正常にアップロード/失敗したことに基づいて、「成功」または「失敗した」トースターを表示する必要があります。私は自分のコードに「約束」を含んでいます。しかし、約束が完了する前でさえ、成功トースターが示されています。ここで何がうまくいかないのか分かりません。誰かがここで私を助けてくれますか?Promiting-Angular 2を待機中

これは、発信者である:

this.multipartupload(params).then((data) => { 

      var fileNameArr = params.Key.split('/') 
      this.uiService.showMessage('success', fileNameArr[fileNameArr.length - 1] + ' Uploaded'); 

     }).catch((err) => { 
     this.uiService.showMessage('warning', err.message); 
     }) 

マルチパートアップロードは、3つの異なる段階で動作します、作成しアップロードして完了します。私は「Complete」ステージが完了した後にのみ成功メッセージを表示したい。以下は、上記のコードから呼び出される「multipartUpload」のコードコード、次のとおりです。

multipartupload(params: any){ 
     var s3 = this.getS3(); 
     var multipartParams = { 
     Bucket: params.Bucket, 
     Key: params.Key, 
     ServerSideEncryption: params.ServerSideEncryption 
     } 

     var partSize = 5 * 1024 * 1024; 
     var partNum = 0; 
     var multipartMap = { 
     Parts: [] 
     }; 
     var numPartsLeft = Math.ceil(params.Body.size/partSize); 
     return s3.createMultipartUpload(multipartParams).promise() 
     .then((data) => { 
      for(var rangeStart = 0; rangeStart < params.Body.size; rangeStart += partSize){ 
      var end = Math.min(rangeStart + partSize, params.Body.size); 
      partNum++; 
      var partParams = { 
       Body: params.Body.slice(rangeStart, end), 
       Bucket: params.Bucket, 
       Key: params.Key, 
       PartNumber: String(partNum), 
       UploadId: data.UploadId 
      } 
      return uploadPart(s3, data, partParams); // -> the toastr is shown at this point. I want it to wait till all the parts are uploaded. 
      } 
     }) 
     .catch((err) => { 
     return err; 
     }) 

     function uploadPart(s3, multipart, partParams, tryNum = 0){ 
     var tryNum = tryNum | 1; 
     s3.uploadPart(partParams).promise() 
      .then(
      (mData) => { 
       multipartMap.Parts[partParams.PartNumber - 1] = { 
       ETag: mData.ETag, 
       PartNumber: Number(partParams.PartNumber) 
       }; 
      if (--numPartsLeft > 0) return; 
      var doneParams = { 
       Bucket: params.Bucket, 
       Key: params.Key, 
       MultipartUpload: multipartMap, 
       UploadId: multipart.UploadId 
      }; 
      return s3.completeMultipartUpload(doneParams).promise().then((data) =>{ 
       return data; 
      }) 
      .catch((err) => { 
       return err; 
      }) 
      }) 
     .catch((multiErr) => { 
      if(tryNum < 3){ 
       uploadPart(s3, multipart, partParams, tryNum + 1); 
      } 
      return multiErr; 
      }) 
     } 
    } 

私はこのコードは少し長くであることを理解しています。しかし、私は全体の文脈を伝えたいと思っていました。理解に感謝。最後の部分がうまくアップロードされるまで誰かがどのように待つかを分かち合うことができたら、私は感謝します。

+0

2つの質問:(1)は 'params.Body.size'は' params.B ody.length'? (2)あなたは 'var tryNum = tryNum | 1;「お願い? –

+0

1)params.Body.sizeはparams.Body.lengthの同義語です。どこでもparams.Body.sizeを使用する必要があります。コードを編集します。 2)ああ! tryNum = tryNum | tryNumの代わりに、tryNumのデフォルト値を1に設定できます。 1 – UnderWood

答えて

1

あなたが欠けているように思われる:forループ

  • に戻り
  • のカップルを生成約束の

    • 集約ここでは、追加の以降の整理整頓のビットです。.. 。

      this.multipartupload(params) 
      .then((data) => { 
          var fileNameArr = params.Key.split('/'); 
          this.uiService.showMessage('success', fileNameArr[fileNameArr.length - 1] + ' Uploaded'); 
      }).catch((err) => { 
          this.uiService.showMessage('warning', err.message); 
      }); 
      
      multipartupload(params: any) { 
          var s3 = this.getS3(), 
           partSize = 5 * 1024 * 1024, 
           partNum = 0, 
           multipartMap = { Parts: [] }; 
          var numPartsLeft = Math.ceil(params.Body.length/partSize); 
          return s3.createMultipartUpload({ 
           Bucket: params.Bucket, 
           Key: params.Key, 
           ServerSideEncryption: params.ServerSideEncryption 
          }).promise() 
          .then((data) => { 
           var promises = []; // <<<<<<< create an array of promises 
           for(var rangeStart = 0; rangeStart < params.Body.length; rangeStart += partSize) { 
            promises.push(uploadPart(s3, data, { 
             Body: params.Body.slice(rangeStart, Math.min(rangeStart + partSize, params.Body.length)), 
             Bucket: params.Bucket, 
             Key: params.Key, 
             PartNumber: String(++partNum), 
             UploadId: data.UploadId 
            }, 1)); 
           } 
           return Promise.all(promises) // <<<<<<< return a single aggregated promise. 
           .then((results => results.filter(res => res !== null))); // filter out any nulls delivered by the (--numPartsLeft > 0) condition below. 
          }); 
      
          function uploadPart(s3, multipart, partParams, tryNum) { 
           return s3.uploadPart(partParams).promise() 
          // ^^^^^^ 
           .then((mData) => { 
            multipartMap.Parts[partParams.PartNumber - 1] = { 
             ETag: mData.ETag, 
             PartNumber: Number(partParams.PartNumber) 
            }; 
            if (--numPartsLeft > 0) { 
             return null; 
            } 
            return s3.completeMultipartUpload({ 
             Bucket: params.Bucket, 
             Key: params.Key, 
             MultipartUpload: multipartMap, 
             UploadId: multipart.UploadId 
            }).promise(); 
           }).catch((multiErr) => (tryNum < 3) ? uploadPart(s3, multipart, partParams, tryNum + 1) : multiErr); // note the implicit return here. 
          } 
      } 
      
    +0

    私はこの部分について疑問を抱いていました。私はそのような約束の集約が可能であることを知らなかった。どうもありがとう。私はそれをチェックさせてください。 – UnderWood

    +0

    私はネイティブのES6(とBluebird)の構文 'Promise.all()'を使用しました。 Angularのように、おそらく '$ q.all()'が必要です。 –