0

I have a function who send chunks of file with an async request (tmp is my chunk)

uploadChunk: function (uploadId, content, offset) {
  var tmp = content.slice(offset, offset + constants.ChunkSize);
  restRequest({
    method: 'POST',
    url: 'file/chunk?uploadId=' + uploadId + '&offset=' + offset,
    data: tmp,
    processData: false,
    contentType: false
  }).then(function (resp) {
    // When the upload is finished, we have an json object with a field '_modelType'
    if (typeof resp._modelType === "undefined" || resp._modelType == null) {
       return this.uploadChunk(uploadId, content, resp.received);
    }
    // Here, file is fully upload
  }.bind(this));
}

I would like to return a promise only when my file is fully upload and use like that:

this.uploadChunk(uploadId, content, 0).then(function (){
  console.log("My file is uploaded");
  .... // use my new file
})

I tried to create a promise but once my function is called recursively, the resolve function is no longer defined..

Need help :)

StudioTime
  • 22,603
  • 38
  • 120
  • 207
Saloukai
  • 1
  • 1

2 Answers2

1

I would like to return a promise only when my file is fully upload and use like that:

What you're proposing doesn't make any logical sense. The whole point of promises (and async code in general) is that they don't finish right away. So even if you could return something later, the original caller of your function would be long gone and unable to receive the value you returned.

Luckily, you're already 98% of the way toward solving this and just don't realize it.

You just need to add the word return here

return restRequest({

The .then() part of your uploadChunk method returns a promise when there is more work to do. This means that the promise you originally return from your uploadChunk function will continue waiting until all of the work is done.

Just try it.

JLRishe
  • 99,490
  • 19
  • 131
  • 169
-1

What about to use callback instead on promise to notify about action completed

uploadChunk: function (uploadId, content, offset, callback) {
  var tmp = content.slice(offset, offset + constants.ChunkSize);
  restRequest({
    method: 'POST',
    url: 'file/chunk?uploadId=' + uploadId + '&offset=' + offset,
    data: tmp,
    processData: false,
    contentType: false
  }).then(function (resp) {
    // When the upload is finished, we have an json object with a field '_modelType'
    if (typeof resp._modelType === "undefined" || resp._modelType == null) {
       return this.uploadChunk(uploadId, content, resp.received, callback);
    }
    // Here, file is fully upload
    callback && callback(resp);
  }.bind(this));
}

Then react to action events in this callbak

this.uploadChunk(uploadId, content, 0, function(resp) {
  console.log("My file is uploaded");
  .... // use my new file
});

So you will be notified each time action completed even when you have recursion.

VadimB
  • 5,533
  • 2
  • 34
  • 48
  • Why a callback? Why not just return a promise OP already has? – Yury Tarabanko Jun 22 '18 at 08:40
  • You are welocme. "Why a callback?" - because here is recursion and you can have several executions in single call. – VadimB Jun 22 '18 at 08:44
  • 1
    "several executions in single call" and? You could return a promise from onFulfill handler. As OP does. Promises are monadic. – Yury Tarabanko Jun 22 '18 at 08:50
  • Using a callback here is like attaching a bike wheel to your car because you don't know how to change its flat tire. Callbacks and promises are like oil and water. Don't mix them! – JLRishe Jun 22 '18 at 08:54