1

First off – we are on untread territory here, so while it works in newest firefoxes, the doc on MDN isn’t ready during the time of writing. I’ll fix the MDN later (maybe, there’s a lot of places that need fixing), so I’ll provide a glossary.

I want to create a Iterator from a callback:

I have a class that is constructed using two callbacks as argument. Let’s call the instance “listener”. This listener then repeatedly calls the first callback with some argument until it is finished listening, then calls the second callback once.

I want to wrap an Iterator around this, which yields each argument that the listener called the first callback with, then throws StopIteration as soon as the second one is called.

Like this:

var magicIter = new MagicIter();

var listener = new Listener(magicIter.ready, magicIter.finished);

//on another thread, listener calls ready(1); ready(2); finished();

exhaustIterator(magicIter); //loops over magicIter and does stuff with it.

//listener has called finished, so magicIter has thrown StopIteration
//so the loop in exhaustIterator has stopped

Note that I’m doing all this in an Addon SDK addon, so i can use promises and related stuff. And don’t need lectures about how browsers don’t know anything what I’m trying to do ;)

/edit: if you ask why i don’t just convert everything to callback-based code have a taste and tell me how to convert that to callback-based code without crying bloody tears. I’ll just wrap my main function into something mentioned here.

Community
  • 1
  • 1
flying sheep
  • 8,475
  • 5
  • 56
  • 73
  • I'm still learning ES6, but that sounds like two iterations (one is the `for..of`, the other one would be the listener calling the callbacks repeatedly). What do you want to achieve with that? – bfavaretto May 22 '13 at 14:44
  • What is confusing me is that you seem to be wanting to mix synchronous and asynchronous operations in a way that might not be possible. – bfavaretto May 22 '13 at 14:51
  • I have that one callback-based thing (the listener), and a function that accepts an iterator (it’s represented by a for-loop here). I’ll change the question to clarify that. It would be a huge pain to change everything to callback-based code, because `exhaustIterator` delegates to subfunctions wich also accept iterators and so on. – flying sheep May 22 '13 at 14:52
  • bfavaretto: Why? If no data is available, `magicIter.next()` should just block until the listener has called `ready()` again. This must be possible, queues can do this, too. – flying sheep May 22 '13 at 15:04

1 Answers1

0

I think you can do something like this with stream.js:

var s = new Stream( 10, 
          function () 
            {
            return new Stream();
            } 
        );
            // the head of the s stream is 10; the tail is the empty stream
            s.print(); // prints 10
            var t = new Stream( 10, 
            function () 
                {
                return new Stream( 20, 
                  function () 
                    {
                    return new Stream( 30, 
                      function () 
                        {
                        return new Stream();
                        } 
                                     );
                     }   
                                 );
                } 
                              );

           /*
           the head of the t stream is 10
           its tail has a head which is 20 
           and a tail which has a head which is 30 
           and a tail which is the empty stream
           */

           t.print(); // prints 10, 20, 30

I want to create a Iterator from a callback:

var callback_iterator =  new Stream( 1, function () {  
  return new Stream(1);  
  } );  

callback_iterator.add(callback_iterator.tail() ).print();

References

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265