If you haven’t seen this idiom before, it is probably going to look like some pretty deep magic, so let’s start with a fruit platter:
<ion-content>
<ion-list>
<ion-item *ngFor="let r of rs"><ion-label [innerText]="r"></ion-label></ion-item>
</ion-list>
<ion-button primary large (click)="eatAll()">nom nom nom</ion-button>
</ion-content>
fruits = ["apple", "banana", "cherry"];
rs: string[] = [];
// arbitrarily wait a second, eat the fruit, and post the result to `rs`.
eat(fruit: string): Promise<void> {
return new Promise(resolve => {
setTimeout(() => {
this.rs.push("finished eating " + fruit + " at " + new Date().toISOString());
resolve();
}, 1000);
});
}
eatAll(): void {
this.rs = []; // blank for a new run
let eater = ((acc, fruit) => acc.then(() => this.eat(fruit)));
return this.fruits.reduce(eater, Promise.resolve());
}
Array.reduce lends itself well to building chains like this, because it allows us to feed the results of one iteration into the next. The chain is seeded with an instantly-resolving Promise, and then each successive run waits on the last one and returns a new Promise on which the next will wait.
So, in your situation (and I do this very rarely), we want to instantiate a Promise manually to promisify the completeCallback parameter:
playOne(track: string): Promise<void> {
return new Promise(resolve => this.nativeAudio.play(track, resolve));
}
playAll(tracks: string[]): void {
let player = (acc, track) => acc.then(() => this.playOne(track));
tracks.reduce(player, Promise.resolve());
}
It’s indeed a deep magic. It worked like a charm. Thank you so much.
But What If I want to call a function while a track is playing. I did it like this but it broke your implementation and made the audio jump to the last track.
I don’t particularly like verToGo as a controller property here, unless it’s needed to be accessed from the template for some other reason, because it’s going to be changing unexpectedly and makes things hard to follow. I would instead make goToVerse take it as an argument. That being said, I still can’t see how it would affect the audio, unless it’s causing an exception to be thrown. Are there any uncaught exceptions in the JavaScript console? I would also experiment with hoisting it out of the Promise:
It worked well…Thank you so much
One more thing though, If I want to repeat a track or list of tracks a number of time. It doesn’t work in my for loop. Should I create a new question for that or it’s something you can just hint me here.
It worked well…Thank you so much
One more thing though, If I want to repeat a track or list of tracks a number of time. It doesn’t work in my for loop. Should I create a new question for that or it’s something you can just hint me here.
In the language of my fruit example, are you saying that if you set fruits to ["apple", "banana", "apple", "banana", "cherry", "cherry"], they don’t play in that order?
But all the audio are playing at the same time, when I set a time out , I saw it they play one after the other, but one doesn’t necessarily finish playing before the other starts .
I know I have worry you too much. any suggestion will be appreciated