1

I have a processor function that takes a "cmd" object and returns a promise where the resolution is the same "cmd" object passed in (with a response key added). reduce here is when.reduce

 reduce = require('when').reduce;

  //return processor(cmds[0])
 return reduce(cmds, function(processor, cmd) {
     Debug.L1('running processor for component ', cmd.component)
     return processor(cmd)
   })
   .then(cmds => {
     Debug.L1('cmds with responses\n', cmds)
     let response = cmds.map(cmd => {
       return cmd.response
     })
     console.log('the complete response is\n', response)
   });

This does nothing, it does get to the .then but the array of promises never fires, never see the Debug running processor...

If I run just a single processor it works great cmd[0], cmds[1], etc.

return processor(cmds[0])
//return reduce(cmds, function(processor,cmd) {
//       Debug.L1('running processor for component ', cmd.component)
//   return processor(cmd) })

What am I missing here? Their api and wiki examples aren't giving me any insight.

IMPORTANT UPDATE: The answer below does work but throws unhandled rejection errors. The culprit is the when library. It seems no longer active and has not been updated since node 6. I switched to bluebird and it works fine without any change to the code outlined below.

DKebler
  • 1,216
  • 1
  • 15
  • 27
  • 1
    Something doesn't seem right, are you use that `processor(cmd)` is supposed to return the next `processor`? Because that's how `reduce()` generally works – Madara's Ghost Oct 25 '16 at 21:42
  • processor does not do that it resolves the object passed. I'm looking for a sequence of promises that allow me to pass in the same object but with on key having a different value. I did have a solution but was looking for something more elegant but maybe when.reduce is not it. See my post that brought me here. http://stackoverflow.com/questions/40206604/a-better-way-to-fire-off-a-sequence-of-the-same-promise-that-have-gets-different – DKebler Oct 26 '16 at 00:11

1 Answers1

1

I'm still not sure what you are looking for, but it might be

reduce(cmds, function(responses, cmd) {
    return processor(cmd).then(function(response) {
        responses.push(response); // or whatever
        return responses;
    });
}, []).then(function(responses) {
    …
});

Before trying to understand when.reduce, you might want to have a look at the non-promise array reduce.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • A way to pass an array of different inputs (actually same object with one key having a different value in each case) to my processor function that returns a promise. It must run in a sequence otherwise it will lock up my serial port (i.e. can't use when.all). when sequence only allows the same input to all calls that's why I was looking for something else. – DKebler Oct 26 '16 at 00:16
  • @DKebler `cmds` is an array of inputs, and each `cmd` gets passed to `processor`? Seems to be exactly what you want. – Bergi Oct 26 '16 at 00:53
  • worked as is by resolving my response instead of the object with response as a key!!!. But works and understanding are two different things. I'm not grokking the equivalence to array.reduce, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce "How Reduce Works" example. When's docs could do better job of explaining the arguments...what is third argument [] about? @bergi you are my special alien presence! thx...yet again. – DKebler Oct 26 '16 at 01:06
  • The only difference to array `reduce` is that the callback returns a promise, not a plain value, and the accumulator (`responses` in the above case) will be the result of that promise. The third argument is the starting value. – Bergi Oct 26 '16 at 01:15
  • 1
    The 2nd argument the "reducer" function is the key to understanding. The first arg of the reducer will be passed from iteration to iteration (explains [],third argl), and the second arg is the current element of the array of promises, values or in my case objects that are being "reduced". Functions like in my case "processor" just need to be in the scope not passed in which was my mistake/confusion. You can do whatever inside in my case just "reduced" by accumulating promise resolutions into an array as when/sequence does. Docs for reducer function could be clearer on this. – DKebler Oct 26 '16 at 16:47
  • once last question - Could I use this to make a FILO queue? I could push more commands onto cmds. Not sure how I get at the individual responses if it hasn't resolved or keep it from resolving if empty. Ideas or suggestions, a library method you recommend? another SO post to check out? – DKebler Oct 26 '16 at 19:19
  • You can search for "promise queue", but I don't think there's a `when` method that does this – Bergi Oct 27 '16 at 00:42