2

I have an array that creates a conversation between two people where it 'flips' between the browser speaking and the browser listening.

Short version, how do I make saySomething queue

 for(var i=0; i < speaks.length; i++) {
     saySomething(speaks[i]);    // saySomething should wait for the previous loop to complete
 }

Long Version

var speak = {}; var speaks = [];
speak.utter = "What do they call a quarter pounder with cheese in Paris?"
speak.speaker = true;
speaks.push(speak);

var speak = {}; 
speak.utter = "They don't call it a quarter pounder with cheese?"
speak.speaker = false;
speak.time = 3;  // listen for 3 seconds
speaks.push(speak);

var speak = {}; 
speak.utter = "They got the metric system. They call it a Royale with cheese"
speak.speaker = true;
speaks.push(speak);

for(var i=0; i < speaks.length; i++) {    //foreach better?
        var speak = speaks[i];
        if(speak.speaker)
              speakThePhrase(speak);    // uses SpeechSynthesisUtterance
        else
              listenAndCompare(speak);  // uses webkitSpeechRecognition
        // don't attempt to speak while listening is happening and vice-versa
    }
 doSomethingElse();    don't process this till old the speaking/listening is done

Originally I had a recursive loop shifting the array and doing much the same as the above but I think this way might be easier to control the queue. So either using jQuery deferred or Javascript Q how would I go about this?

Gazzer
  • 4,524
  • 10
  • 39
  • 49
  • Irregardless of the actual question, a note: You're constantly changing the same object (`speak`), pushing it onto the array will not make a copy! – Yoshi Sep 30 '15 at 09:30
  • 3
    [Promisify](http://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) the speech synthesis API call (listen to onend) and then [queue them in a loop](http://stackoverflow.com/questions/24586110/resolve-promises-one-after-another-i-e-in-sequence/24586168#24586168). – Benjamin Gruenbaum Sep 30 '15 at 09:34

1 Answers1

0

You are not creating a queue of object you are just shadowing the same objects and pushing it again into the speaks array, so you will get the last version of your object several times inside the array.

If you want to create an async behavior you should try callbacks instead of a simple for loop.

It would be better do something like this:

var speak = [
    {
        utter: "What do they call a quarter pounder with cheese in Paris?",
        speaker: true
    },
    {
        utter: "They don't call it a quarter pounder with cheese?",
        speaker: false,
        time: 3
    },
    {
        utter: "They got the metric system. They call it a Royale with cheese",
        speaker: true
    }
];

Then you can use array methods like filter and map to handle the data you need.

Finally, you can use events to trigger each speaking when something in you application happens.

David Gomez
  • 2,762
  • 2
  • 18
  • 28
  • Sorry, can you clarify. speak is reset each time it is pushed into the speaks array with a `var speak = {}` (that was the edit). So the `speaks` array contains the phrases, and the callbacks are within the `speakThePhrase` and `listenAndCompare` functions. – Gazzer Oct 02 '15 at 06:26
  • Each object inside the array will be referencing to the same data, you are not creating a copy of the object with the push method, you are just changing the reference to the data in the memory. – David Gomez Oct 02 '15 at 11:17
  • With this fiddle, http://jsfiddle.net/macgroover/xwq26Lak/2/ the correct utterances appear. I'm not sure I understand the problem. – Gazzer Oct 03 '15 at 09:53
  • Check my updated comment, maybe can help you to understand my idea on how you should create your objects. – David Gomez Oct 04 '15 at 03:43
  • Thanks - I appreciate it. But I still don't see how the `var speak` you have created is different from the `var speaks` in my example. (In reality the speaks array can be of any length as it is grabbed from a conversation in HTML). – Gazzer Oct 04 '15 at 05:05