Video playback loop using promise chaining and setTimeout











up vote
1
down vote

favorite












Well this could seem redundant given the numerous topic about interaction between Promises and setTimeout but I can't find an answer that exactly fit my case (or that I am capable of interpreting !)



In the case of a Video player API usage, I need to loop on a sequence, and exit the loop when a certain condition is reached.



The following code works, but I was wondering if there was a sexier way, using Promise chaining instead of this :



export class LoopStep {
// looping from 0 to 5 seconds in the video
this.duration = 5;
this.start = 0;

onStart() { // entry point
return this.onLoop();
}

onLoop() {
return new Promise((resolve) => {
this.loopAndResolve(resolve);
});
}

loopAndResolve(resolve) { // start loop
if(this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(this.loopAndResolve.bind(this, resolve), this.duration * 1000); // callback
} else {
resolve();
}
}
}

// Anywhere else
loopStep.onStart.then(()=> console.log('exiting loop successfully')); // OK


Actually I would find more appropriated to avoid passing the "resolve" function as a parameter (only because I have a feeling that this could be wrong, or at least not "the most efficient/sexy").










share|improve this question
















bumped to the homepage by Community 1 min ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • You can simply embed loopAndResolve as a named function inside onLoop so there'll be no need to pass resolve.
    – wOxxOm
    Feb 7 at 5:28















up vote
1
down vote

favorite












Well this could seem redundant given the numerous topic about interaction between Promises and setTimeout but I can't find an answer that exactly fit my case (or that I am capable of interpreting !)



In the case of a Video player API usage, I need to loop on a sequence, and exit the loop when a certain condition is reached.



The following code works, but I was wondering if there was a sexier way, using Promise chaining instead of this :



export class LoopStep {
// looping from 0 to 5 seconds in the video
this.duration = 5;
this.start = 0;

onStart() { // entry point
return this.onLoop();
}

onLoop() {
return new Promise((resolve) => {
this.loopAndResolve(resolve);
});
}

loopAndResolve(resolve) { // start loop
if(this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(this.loopAndResolve.bind(this, resolve), this.duration * 1000); // callback
} else {
resolve();
}
}
}

// Anywhere else
loopStep.onStart.then(()=> console.log('exiting loop successfully')); // OK


Actually I would find more appropriated to avoid passing the "resolve" function as a parameter (only because I have a feeling that this could be wrong, or at least not "the most efficient/sexy").










share|improve this question
















bumped to the homepage by Community 1 min ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • You can simply embed loopAndResolve as a named function inside onLoop so there'll be no need to pass resolve.
    – wOxxOm
    Feb 7 at 5:28













up vote
1
down vote

favorite









up vote
1
down vote

favorite











Well this could seem redundant given the numerous topic about interaction between Promises and setTimeout but I can't find an answer that exactly fit my case (or that I am capable of interpreting !)



In the case of a Video player API usage, I need to loop on a sequence, and exit the loop when a certain condition is reached.



The following code works, but I was wondering if there was a sexier way, using Promise chaining instead of this :



export class LoopStep {
// looping from 0 to 5 seconds in the video
this.duration = 5;
this.start = 0;

onStart() { // entry point
return this.onLoop();
}

onLoop() {
return new Promise((resolve) => {
this.loopAndResolve(resolve);
});
}

loopAndResolve(resolve) { // start loop
if(this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(this.loopAndResolve.bind(this, resolve), this.duration * 1000); // callback
} else {
resolve();
}
}
}

// Anywhere else
loopStep.onStart.then(()=> console.log('exiting loop successfully')); // OK


Actually I would find more appropriated to avoid passing the "resolve" function as a parameter (only because I have a feeling that this could be wrong, or at least not "the most efficient/sexy").










share|improve this question















Well this could seem redundant given the numerous topic about interaction between Promises and setTimeout but I can't find an answer that exactly fit my case (or that I am capable of interpreting !)



In the case of a Video player API usage, I need to loop on a sequence, and exit the loop when a certain condition is reached.



The following code works, but I was wondering if there was a sexier way, using Promise chaining instead of this :



export class LoopStep {
// looping from 0 to 5 seconds in the video
this.duration = 5;
this.start = 0;

onStart() { // entry point
return this.onLoop();
}

onLoop() {
return new Promise((resolve) => {
this.loopAndResolve(resolve);
});
}

loopAndResolve(resolve) { // start loop
if(this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(this.loopAndResolve.bind(this, resolve), this.duration * 1000); // callback
} else {
resolve();
}
}
}

// Anywhere else
loopStep.onStart.then(()=> console.log('exiting loop successfully')); // OK


Actually I would find more appropriated to avoid passing the "resolve" function as a parameter (only because I have a feeling that this could be wrong, or at least not "the most efficient/sexy").







javascript promise






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 7 at 19:44









200_success

127k15149412




127k15149412










asked Feb 5 at 13:58









Kleioz

61




61





bumped to the homepage by Community 1 min ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







bumped to the homepage by Community 1 min ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.














  • You can simply embed loopAndResolve as a named function inside onLoop so there'll be no need to pass resolve.
    – wOxxOm
    Feb 7 at 5:28


















  • You can simply embed loopAndResolve as a named function inside onLoop so there'll be no need to pass resolve.
    – wOxxOm
    Feb 7 at 5:28
















You can simply embed loopAndResolve as a named function inside onLoop so there'll be no need to pass resolve.
– wOxxOm
Feb 7 at 5:28




You can simply embed loopAndResolve as a named function inside onLoop so there'll be no need to pass resolve.
– wOxxOm
Feb 7 at 5:28










1 Answer
1






active

oldest

votes

















up vote
0
down vote













You could try something like this:



export class LoopStep {
public onStart(): Promise<void> { // entry point
return this.onLoop();
}

private onLoop(): Promise<void> {
return this.loopAndResolve();
}

private loopAndResolve(): Promise<void> { // start loop
if (this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(() => this.loopAndResolve(), this.duration * 1000);
} else {
return Promise.resolve();
}
}
}

// Anywhere else
loopsStep.onStart().then(() => console.log('exiting loop successfully')); // OK


One of the best things of Typescript is the type safety. It's easier to keep track of the promises you're passing from one function to another if you declare them in the return type.



In your case, where you just want a cleaner way to resolve a Promise, you can use Promise.resolve();. It's pretty straightforward to use and very useful. DOCS



(Don't forget the parenthesis when calling onStart!)






share|improve this answer























  • I see your point. Nevertheless I'm not sure how to combine it with setTimeout. return Promise.resolve(setTimeout(this.onLoop.bind(this), this.duration * 1000) as return statement in onLoop() ?
    – Kleioz
    Feb 7 at 10:08












  • Then I'm failing to understand the goal. Do you need to execute onLoop() a set amount of times? Do you need to do it indefinitely but everytime after some delay? It might also help what player is and what does play() do or return.
    – alrodseg
    Feb 7 at 13:09










  • I need to call "this.player.setTime(5)" every 10 seconds for example, so that my video can loop indefinetly from 00:05 to 00:15. My implementatio nactually works (the parenthesis missing are a copy/paste mistake). Now what I was wondering is if there were a prettier way to implement it without passing the "resolve" as parameter. playeris a video player API (vimeo, but this is no big deal) play() launches the video and returns a Promise. So what I need to do is call onLoop() every 5 seconds until "this.isLooping" is set to false somewhere else in my app.
    – Kleioz
    Feb 7 at 14:46










  • wOxxOm comment on my OP is, for example, a decent solution. Your suggestion is also correct but misses the setTimeout part. Which is causing me troubles to use with Promises :)
    – Kleioz
    Feb 7 at 14:48












  • Please check the edited answer. I've just done a few changes to your code, but now it looks kinda redundant to have onStart() and onLoop() :D I hope it will give you an idea on how to proceed. If you need help tweaking it, just ask ;)
    – alrodseg
    Feb 7 at 15:42











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186824%2fvideo-playback-loop-using-promise-chaining-and-settimeout%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













You could try something like this:



export class LoopStep {
public onStart(): Promise<void> { // entry point
return this.onLoop();
}

private onLoop(): Promise<void> {
return this.loopAndResolve();
}

private loopAndResolve(): Promise<void> { // start loop
if (this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(() => this.loopAndResolve(), this.duration * 1000);
} else {
return Promise.resolve();
}
}
}

// Anywhere else
loopsStep.onStart().then(() => console.log('exiting loop successfully')); // OK


One of the best things of Typescript is the type safety. It's easier to keep track of the promises you're passing from one function to another if you declare them in the return type.



In your case, where you just want a cleaner way to resolve a Promise, you can use Promise.resolve();. It's pretty straightforward to use and very useful. DOCS



(Don't forget the parenthesis when calling onStart!)






share|improve this answer























  • I see your point. Nevertheless I'm not sure how to combine it with setTimeout. return Promise.resolve(setTimeout(this.onLoop.bind(this), this.duration * 1000) as return statement in onLoop() ?
    – Kleioz
    Feb 7 at 10:08












  • Then I'm failing to understand the goal. Do you need to execute onLoop() a set amount of times? Do you need to do it indefinitely but everytime after some delay? It might also help what player is and what does play() do or return.
    – alrodseg
    Feb 7 at 13:09










  • I need to call "this.player.setTime(5)" every 10 seconds for example, so that my video can loop indefinetly from 00:05 to 00:15. My implementatio nactually works (the parenthesis missing are a copy/paste mistake). Now what I was wondering is if there were a prettier way to implement it without passing the "resolve" as parameter. playeris a video player API (vimeo, but this is no big deal) play() launches the video and returns a Promise. So what I need to do is call onLoop() every 5 seconds until "this.isLooping" is set to false somewhere else in my app.
    – Kleioz
    Feb 7 at 14:46










  • wOxxOm comment on my OP is, for example, a decent solution. Your suggestion is also correct but misses the setTimeout part. Which is causing me troubles to use with Promises :)
    – Kleioz
    Feb 7 at 14:48












  • Please check the edited answer. I've just done a few changes to your code, but now it looks kinda redundant to have onStart() and onLoop() :D I hope it will give you an idea on how to proceed. If you need help tweaking it, just ask ;)
    – alrodseg
    Feb 7 at 15:42















up vote
0
down vote













You could try something like this:



export class LoopStep {
public onStart(): Promise<void> { // entry point
return this.onLoop();
}

private onLoop(): Promise<void> {
return this.loopAndResolve();
}

private loopAndResolve(): Promise<void> { // start loop
if (this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(() => this.loopAndResolve(), this.duration * 1000);
} else {
return Promise.resolve();
}
}
}

// Anywhere else
loopsStep.onStart().then(() => console.log('exiting loop successfully')); // OK


One of the best things of Typescript is the type safety. It's easier to keep track of the promises you're passing from one function to another if you declare them in the return type.



In your case, where you just want a cleaner way to resolve a Promise, you can use Promise.resolve();. It's pretty straightforward to use and very useful. DOCS



(Don't forget the parenthesis when calling onStart!)






share|improve this answer























  • I see your point. Nevertheless I'm not sure how to combine it with setTimeout. return Promise.resolve(setTimeout(this.onLoop.bind(this), this.duration * 1000) as return statement in onLoop() ?
    – Kleioz
    Feb 7 at 10:08












  • Then I'm failing to understand the goal. Do you need to execute onLoop() a set amount of times? Do you need to do it indefinitely but everytime after some delay? It might also help what player is and what does play() do or return.
    – alrodseg
    Feb 7 at 13:09










  • I need to call "this.player.setTime(5)" every 10 seconds for example, so that my video can loop indefinetly from 00:05 to 00:15. My implementatio nactually works (the parenthesis missing are a copy/paste mistake). Now what I was wondering is if there were a prettier way to implement it without passing the "resolve" as parameter. playeris a video player API (vimeo, but this is no big deal) play() launches the video and returns a Promise. So what I need to do is call onLoop() every 5 seconds until "this.isLooping" is set to false somewhere else in my app.
    – Kleioz
    Feb 7 at 14:46










  • wOxxOm comment on my OP is, for example, a decent solution. Your suggestion is also correct but misses the setTimeout part. Which is causing me troubles to use with Promises :)
    – Kleioz
    Feb 7 at 14:48












  • Please check the edited answer. I've just done a few changes to your code, but now it looks kinda redundant to have onStart() and onLoop() :D I hope it will give you an idea on how to proceed. If you need help tweaking it, just ask ;)
    – alrodseg
    Feb 7 at 15:42













up vote
0
down vote










up vote
0
down vote









You could try something like this:



export class LoopStep {
public onStart(): Promise<void> { // entry point
return this.onLoop();
}

private onLoop(): Promise<void> {
return this.loopAndResolve();
}

private loopAndResolve(): Promise<void> { // start loop
if (this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(() => this.loopAndResolve(), this.duration * 1000);
} else {
return Promise.resolve();
}
}
}

// Anywhere else
loopsStep.onStart().then(() => console.log('exiting loop successfully')); // OK


One of the best things of Typescript is the type safety. It's easier to keep track of the promises you're passing from one function to another if you declare them in the return type.



In your case, where you just want a cleaner way to resolve a Promise, you can use Promise.resolve();. It's pretty straightforward to use and very useful. DOCS



(Don't forget the parenthesis when calling onStart!)






share|improve this answer














You could try something like this:



export class LoopStep {
public onStart(): Promise<void> { // entry point
return this.onLoop();
}

private onLoop(): Promise<void> {
return this.loopAndResolve();
}

private loopAndResolve(): Promise<void> { // start loop
if (this.isLooping) { // exit condition when turned to false
this.player.setTime(this.start);
this.player.play();
setTimeout(() => this.loopAndResolve(), this.duration * 1000);
} else {
return Promise.resolve();
}
}
}

// Anywhere else
loopsStep.onStart().then(() => console.log('exiting loop successfully')); // OK


One of the best things of Typescript is the type safety. It's easier to keep track of the promises you're passing from one function to another if you declare them in the return type.



In your case, where you just want a cleaner way to resolve a Promise, you can use Promise.resolve();. It's pretty straightforward to use and very useful. DOCS



(Don't forget the parenthesis when calling onStart!)







share|improve this answer














share|improve this answer



share|improve this answer








edited Feb 7 at 15:40

























answered Feb 7 at 9:46









alrodseg

264




264












  • I see your point. Nevertheless I'm not sure how to combine it with setTimeout. return Promise.resolve(setTimeout(this.onLoop.bind(this), this.duration * 1000) as return statement in onLoop() ?
    – Kleioz
    Feb 7 at 10:08












  • Then I'm failing to understand the goal. Do you need to execute onLoop() a set amount of times? Do you need to do it indefinitely but everytime after some delay? It might also help what player is and what does play() do or return.
    – alrodseg
    Feb 7 at 13:09










  • I need to call "this.player.setTime(5)" every 10 seconds for example, so that my video can loop indefinetly from 00:05 to 00:15. My implementatio nactually works (the parenthesis missing are a copy/paste mistake). Now what I was wondering is if there were a prettier way to implement it without passing the "resolve" as parameter. playeris a video player API (vimeo, but this is no big deal) play() launches the video and returns a Promise. So what I need to do is call onLoop() every 5 seconds until "this.isLooping" is set to false somewhere else in my app.
    – Kleioz
    Feb 7 at 14:46










  • wOxxOm comment on my OP is, for example, a decent solution. Your suggestion is also correct but misses the setTimeout part. Which is causing me troubles to use with Promises :)
    – Kleioz
    Feb 7 at 14:48












  • Please check the edited answer. I've just done a few changes to your code, but now it looks kinda redundant to have onStart() and onLoop() :D I hope it will give you an idea on how to proceed. If you need help tweaking it, just ask ;)
    – alrodseg
    Feb 7 at 15:42


















  • I see your point. Nevertheless I'm not sure how to combine it with setTimeout. return Promise.resolve(setTimeout(this.onLoop.bind(this), this.duration * 1000) as return statement in onLoop() ?
    – Kleioz
    Feb 7 at 10:08












  • Then I'm failing to understand the goal. Do you need to execute onLoop() a set amount of times? Do you need to do it indefinitely but everytime after some delay? It might also help what player is and what does play() do or return.
    – alrodseg
    Feb 7 at 13:09










  • I need to call "this.player.setTime(5)" every 10 seconds for example, so that my video can loop indefinetly from 00:05 to 00:15. My implementatio nactually works (the parenthesis missing are a copy/paste mistake). Now what I was wondering is if there were a prettier way to implement it without passing the "resolve" as parameter. playeris a video player API (vimeo, but this is no big deal) play() launches the video and returns a Promise. So what I need to do is call onLoop() every 5 seconds until "this.isLooping" is set to false somewhere else in my app.
    – Kleioz
    Feb 7 at 14:46










  • wOxxOm comment on my OP is, for example, a decent solution. Your suggestion is also correct but misses the setTimeout part. Which is causing me troubles to use with Promises :)
    – Kleioz
    Feb 7 at 14:48












  • Please check the edited answer. I've just done a few changes to your code, but now it looks kinda redundant to have onStart() and onLoop() :D I hope it will give you an idea on how to proceed. If you need help tweaking it, just ask ;)
    – alrodseg
    Feb 7 at 15:42
















I see your point. Nevertheless I'm not sure how to combine it with setTimeout. return Promise.resolve(setTimeout(this.onLoop.bind(this), this.duration * 1000) as return statement in onLoop() ?
– Kleioz
Feb 7 at 10:08






I see your point. Nevertheless I'm not sure how to combine it with setTimeout. return Promise.resolve(setTimeout(this.onLoop.bind(this), this.duration * 1000) as return statement in onLoop() ?
– Kleioz
Feb 7 at 10:08














Then I'm failing to understand the goal. Do you need to execute onLoop() a set amount of times? Do you need to do it indefinitely but everytime after some delay? It might also help what player is and what does play() do or return.
– alrodseg
Feb 7 at 13:09




Then I'm failing to understand the goal. Do you need to execute onLoop() a set amount of times? Do you need to do it indefinitely but everytime after some delay? It might also help what player is and what does play() do or return.
– alrodseg
Feb 7 at 13:09












I need to call "this.player.setTime(5)" every 10 seconds for example, so that my video can loop indefinetly from 00:05 to 00:15. My implementatio nactually works (the parenthesis missing are a copy/paste mistake). Now what I was wondering is if there were a prettier way to implement it without passing the "resolve" as parameter. playeris a video player API (vimeo, but this is no big deal) play() launches the video and returns a Promise. So what I need to do is call onLoop() every 5 seconds until "this.isLooping" is set to false somewhere else in my app.
– Kleioz
Feb 7 at 14:46




I need to call "this.player.setTime(5)" every 10 seconds for example, so that my video can loop indefinetly from 00:05 to 00:15. My implementatio nactually works (the parenthesis missing are a copy/paste mistake). Now what I was wondering is if there were a prettier way to implement it without passing the "resolve" as parameter. playeris a video player API (vimeo, but this is no big deal) play() launches the video and returns a Promise. So what I need to do is call onLoop() every 5 seconds until "this.isLooping" is set to false somewhere else in my app.
– Kleioz
Feb 7 at 14:46












wOxxOm comment on my OP is, for example, a decent solution. Your suggestion is also correct but misses the setTimeout part. Which is causing me troubles to use with Promises :)
– Kleioz
Feb 7 at 14:48






wOxxOm comment on my OP is, for example, a decent solution. Your suggestion is also correct but misses the setTimeout part. Which is causing me troubles to use with Promises :)
– Kleioz
Feb 7 at 14:48














Please check the edited answer. I've just done a few changes to your code, but now it looks kinda redundant to have onStart() and onLoop() :D I hope it will give you an idea on how to proceed. If you need help tweaking it, just ask ;)
– alrodseg
Feb 7 at 15:42




Please check the edited answer. I've just done a few changes to your code, but now it looks kinda redundant to have onStart() and onLoop() :D I hope it will give you an idea on how to proceed. If you need help tweaking it, just ask ;)
– alrodseg
Feb 7 at 15:42


















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186824%2fvideo-playback-loop-using-promise-chaining-and-settimeout%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Feedback on college project

Futebolista

Albești (Vaslui)