javascript - 等待 Promise-Angular 2

标签 javascript amazon-web-services asynchronous angular promise

我正在使用 Angular2 构建一个应用程序。我正在尝试将分段上传到 Amazon S3。我需要根据成功上传/失败的对象来显示“成功”或“失败” toastr 。我的代码中有“ promise ”。但即使在 promise 完成之前,成功的 toastr 就已经被展示出来了。我不确定这里出了什么问题。有人可以帮我吗?

这是来电者:

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'的代码,它是从上面的代码中调用的:

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;
          })
      }
    }

我知道这段代码有点长。但我想传达整个背景。感谢您的理解。如果有人可以分享如何等待最后一部分成功上传,我将不胜感激。

最佳答案

看来您失踪了:

  • for循环中生成的promise的聚合
  • 一些返回

这是一些额外的整理......

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.
    }
}

关于javascript - 等待 Promise-Angular 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38362675/

相关文章:

javascript - TypeError [ERR_INVALID_ARG_TYPE] : The "original" argument must be of type Function. 接收类型未定义

javascript - 使用 AJAX 重新加载 html 页面

python - 无法在 aws CDK 中找到 select_subnets 函数

javascript - 中间件不会捕获带有等待的 Promise 拒绝

javascript - 在 React 中处理巨大的 10 列表排序的最佳方法?

javascript - three.js:相机改变位置,但不显示

python - AWS Lambda S3 复制到 Postgres 成功但不复制数据

amazon-web-services - 通过 Amplify Auth 获取登录用户的凭据

multithreading - "any"代码的 Perl 异步任务,不管它是什么?

javascript - 将数据传递回异步请求的调用函数