0

I'm new to use promise and Q, I'm sure I'm not doing correctly,
please give me some suggestion,

can I use fcall inside fcall? because there is a for loop I want to make sure each item image[i] process a list promise function flow..

I need the response from beginning to end, input to each promise function then pass to next flow the end return to client side,
but I don't get how to deal with the loop

var response = {};

Q.fcall(function() {
  // validate request ... 
  return response;
})
.then(function(response) {
  // save file
  for (var i = 0; i < images.length; i++) {
    Q.fcall(function() {
      // do something with images[i]
      return response;
    })
    .then(function(response) {
      // do something with images[i]
      return response;
    })
    .fail(function(error, response) {
      response.error = error;
      res.send(response);
    })
    .done(function(response) {
      return response;
    }) 
  }

  return response;  << I want this response append data from above loop if above loop all success, then to next flow save db query, if one fail then res.send(), not execute all after 
})
.then(function(response) {
  // save db query ...
  return response
})
.fail(function(error, response) {
  response.error = error;
  res.send(response);
}).done(function(response) {
  res.send(response);
});
user1575921
  • 1,078
  • 1
  • 16
  • 29
  • at the moment reponse returned from `.done` in the image processing chain is lost in nowhere. Read about `Q.All`. Make an array of promises (chains that you create in `for` loop) and use `Q.All` – Kirill Slatin Mar 21 '16 at 09:00
  • thanks for reply, in image process chain they need to one done then to next if use q.all able to do the same thing? – user1575921 Mar 21 '16 at 09:15
  • Do you need to process one image strictly after another? or just do two different things on each image? – Kirill Slatin Mar 21 '16 at 09:17
  • two different things on each image but need to do first thing then next thing – user1575921 Mar 21 '16 at 09:24
  • Then I assume from your questions that you miss one conceptual point. A chain of promises is also a promise. So when you do `Q.fcall.then(process1).then(process2).fail(handleImageError)` it is a promise itself. And `process1` and `process2` will be fulfilled strictly one after another (assuming none of them fails). Now you can put them into array. Something like `return Q.All(images.map(function(image){ return Q.fcall(process1).then(process2).fail(...)}))` – Kirill Slatin Mar 21 '16 at 09:27
  • should I put Q.All inside the for loop? – user1575921 Mar 21 '16 at 09:34

1 Answers1

1

Given that images from the response can be processed simultaneously you can use Q.All to ensure that all images are processed successfully

Q.fcall(verifyRequest)
.then(function(){
    return Q.All(images.map(function(image){ 
        return Q.fcall(process1)
            .then(process2)
            .fail(handleImageError)
        }));
    })
.then(saveToDB)
.fail(handleRequestError)

Now all you have to do is implement the functions properly making sure data flow is correct.

Make sure that from handleImageError you return a rejection (return Q.reject();). Since fail can absorb errors if nothing returned. Actually from your code I think you don't need this handler (process each image failure) because there will be one handler that will respond with error if any of the images fails

Kirill Slatin
  • 6,085
  • 3
  • 18
  • 38