0

Edit 2: So I changed things to use setTimeOut instead and that did the trick. See the accepted answer for what was causing the actual error. The code below works fine.

async function getSlices() {
    const imgBuffs = await sliceImg('./example.png', 128, 128)
    let saveInd = 0
    for (const buff of imgBuffs) {
        const asciified = await asciify(buff, options)
        console.log(asciified)
        await setTimeout(() => {}, 1000)
        await execShellCommand(`clear | import -window root -crop 904x904+0+66 ${saveInd}.png`).then((res, rej) => saveInd++)
        await setTimeout(() => {}, 1000)
    }

}

Edit: Added missing important code

The following function slices images and turns them into ascii (this works). Then, the function is supposed to console.log the data, wait a little, take a screenshot, wait again and then move on to the next saved buffer. Without delays, the function works, but it takes badly timed screenshots. With the await delays, the function stops at the first delay.

async function getSlices() {
    const imgBuffs = await sliceImg('./example.png', 128, 128)
    for (const buff of imgBuffs) {
        console.log('Starting to wait for asciified')
        const asciified = await asciify(buff, options)
        console.log(asciified)
        console.log('Ascifiied done, waiting for first delay')
// the function stops here...
        await delay(100)
        console.log('executing the command')
        await execShellCommand('clear | import -window root -crop 904x904+0+66  Image2.png').then((res, rej) => console.log('Shot saved'))
        await delay(100)
        console.log('all done')
}

async function execShellCommand(cmd) {
    const exec = require('child_process').exec;
    return new Promise((resolve, reject) => {
        exec(cmd, (error, stdout, stderr) => {
            if (error) {
                console.log(error);
            }
            console.log('here')
            resolve(stdout ? stdout : stderr);
        });
    });
}

const delay = ms => new Promise(res => setTimeout(res, ms));
VictoriaStudios
  • 135
  • 1
  • 9
  • What is `execShellCommand()`? Is it synchronous or asynchronous. I would guess that it's asynchronous and you aren't allowing your `for` loop to wait for it. – jfriend00 Nov 12 '22 at 17:50
  • 2
    just doing `someAsyncMethod().then()` within an `async` codeblock does not wait until the `then` resolves ... use `await execShellCommand(..).then(...)` – derpirscher Nov 12 '22 at 17:52
  • and what is `delay`? This might have a similar problem – derpirscher Nov 12 '22 at 17:53
  • I just added the missing code you guys requested. I also added an wait statement for the execShell thingy... but the result is still the same. – VictoriaStudios Nov 12 '22 at 17:56
  • Could you please post the log output you're getting? – Bergi Nov 12 '22 at 18:07
  • How/where is this function called? It should work fine - maybe something else is terminating the process? – Bergi Nov 12 '22 at 18:07
  • BTW since node 15 you don't need to create your own `delay` but you can use [`setTimeout`](https://nodejs.org/api/timers.html#timerspromisessettimeoutdelay-value-options) from the `timers/promises` API – derpirscher Nov 12 '22 at 18:49
  • Here's the console output: node index.js Starting to wait for asciified --big ascii picture here --- Ascifiied done, waiting for first delay – VictoriaStudios Nov 12 '22 at 18:52
  • This may well be an [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem/233676#233676). There's likely a better way to make a video of ASCII characters if that's what you're trying to do. – ggorlen Nov 12 '22 at 18:57
  • @ggorlen Yes, there probably is for this special usecase. But still, executing some async steps in a loop with some delay in between them is a totally valid pattern and there is no reason the above code -- especially the `delay` -- shouldn't work. – derpirscher Nov 12 '22 at 19:01
  • `await setTimeout(() => {}, 1000)` is not correct. Either you should use your `delay` function (but call it only after definition - or use a function declaration!), or if you import `timers/promises` then it's `await setTimeout(1000);`. – Bergi Nov 12 '22 at 21:47

1 Answers1

0

You probably get

Cannot access 'delay' before initialization

You don't have any catch or try..catch blocks so you don't see the error

Invisible error:

async function getSlices() {
  console.log('Starting to wait for asciified')
  await delay(100)
  console.log('all done')
}

getSlices()

const delay = ms => new Promise(res => setTimeout(res, ms));

Visible with catch:

async function getSlices() {
  console.log('Starting to wait for asciified')
  await delay(100)
  console.log('all done')
}

getSlices().catch(console.error)

const delay = ms => new Promise(res => setTimeout(res, ms));
Konrad
  • 21,590
  • 4
  • 28
  • 64
  • 1
    Yes, this was it. I had already changed the code to setTimeout. Reverting my HEAD to this one, yes, it wasn't initialized. – VictoriaStudios Nov 12 '22 at 19:10
  • 1
    Could be useful: https://stackoverflow.com/questions/43834559/how-to-find-which-promises-are-unhandled-in-node-js-unhandledpromiserejectionwar – Konrad Nov 12 '22 at 19:11