-3

I have a piece of code:

var a = false;

function wait(milliseconds, async) {
if(!async) {
setTimeout(function() {
        console.log('Sync timer done.');
        a = true;
        return true;
    }, milliseconds*1000);
}
(...)
f_recipe.forEach(function(item, index) {
    if (obj['actual_step'] != 0 && obj['actual_step'] != index ) {
            e = "Desync";
        throw e;
    };
    console.log("Step: " + obj.actual_step);
    if(item.substr(item.length - 6) != "false)"){
        if (eval(item)) {
        obj['actual_step']++;
        }
    } else {
        eval(item);
        var ival = setInterval(function(){
            if(a) {
                console.log('do the next thing');
                clearInterval(ival);
            }
        }, 1000);
    }
});

But when I get to 'do the next thing'(interval complete), the forEach loop doesn't continue to the next element of the array. 'a' is set to true after timeout (kind of a synchronous wait in JS). f_recipes is a string array with function call (e.g. 'wait(20, false)').

How to get it to work?

sofalse
  • 67
  • 1
  • 13
  • I don't think the interval's function will have the context you're expecting. – DBS Oct 26 '17 at 13:58
  • What is `a`? Where is it being set? Please explain what this code is supposed to do instead of expecting us to decipher it. – JLRishe Oct 26 '17 at 13:59
  • 1
    It's not really clear what the code is supposed to be doing, but I'm pretty sure this is a wrong approach altogether. – JJJ Oct 26 '17 at 13:59
  • 'a' is described below the code... – sofalse Oct 26 '17 at 13:59
  • @user1798217 The description below the code doesn't answer my question. What timeout? Where? – JLRishe Oct 26 '17 at 14:00
  • I've updated the code. – sofalse Oct 26 '17 at 14:02
  • 3
    I don't know why you would expect the `forEach` to continue to the next item after the interval is done. The `forEach` completes synchronously long before the interval even starts. You still haven't explained what this code is supposed to do. – JLRishe Oct 26 '17 at 14:03
  • This code is supposed to eval() each item of the array. But when it's synchronous wait(checked with substr), it should behave differently, because setTimeout is asynchronous and that's what I invented for it. – sofalse Oct 26 '17 at 14:07
  • 1
    @user1798217 Why are you using `eval` for this? Why is the code stored in strings instead of functions? This seems very ill-conceived. – JLRishe Oct 26 '17 at 14:11
  • It's stored in strings because instruction list is downloaded from sqlite (basically a string containing things like "do(this);wait(this);check(this)"; this string is splitted by ";" and functions are being evaluated each after another). – sofalse Oct 26 '17 at 14:13
  • @user1798217 Ok. What is that `actual_step` stuff supposed to do? – JLRishe Oct 26 '17 at 14:23
  • Actual step is just an info for front-end, telling him which step of instruction list is running.Error throw prevents from front- and back-end desync (just in case). Oh, it should be also incremented when a is true, but it isn't an issue (app doesn't throw desync error) – sofalse Oct 26 '17 at 14:31
  • Possible duplicate of [What is the JavaScript version of sleep()?](https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep) – JJJ Oct 26 '17 at 14:48

1 Answers1

0

What you're trying to do seems like a very bad idea, but promises can help with this (using Bluebird here because it provides Promise.delay and Promise.each):

function wait(seconds, dontActuallyWait) {
  return dontActuallyWait ? null : Promise.delay(seconds * 1000);
}

function runSequence(things) {
  return Promise.each(things, function(thing) {
    return eval(thing);
  });
}

runSequence([
  'console.log("hello")',
  'wait(2, false)',
  'console.log("hello again")',
  'wait(5, false)',
  'console.log("goodbye")'
]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.1/bluebird.min.js"></script>
JLRishe
  • 90,548
  • 14
  • 117
  • 150