javascript - "Sova" exekvering inuti asynkron iteration "for await" (ES2018)


Jag använder asynkron iteration för att hämta objekt från DynamoDB. För varje iteration (objekt) kör jag några HTTP-förfrågningar. Jag behöver "sova" 1 sekund i varje iteration för att begränsa förfrågningsflödet. Jag försökte med promisify(setTimeout) men körningen stannar.

const sleep = require('util').promisify(setTimeout)

for await (const item of mapper.scan(MyDomainObject)) {

    await sleep(1000);   //This doesn't work
    // do some http requests
}

Vad är det rätta sättet att "sova" inne i en "for await"-iteration?

Svar #1

Jag listade ut det. Problemet var att jag körde koden med Jest. När jag körde koden normalt fungerade koden ovan perfekt. Tack vare Noseratios svar tittade jag någon annanstans. Jag var för fokuserad på for await.

Svar #2

Din kod verkar vara korrekt, jag har simulerat din asynkrona generator på detta sätt:

const sleep = require('util').promisify(setTimeout);

async function* scan(arg) {
  for (let i = 0; i < 4; i++) {
    console.log(`yielding ${i}`);
    await sleep(500);
    yield i;
  }
}

async function test()
{
  for await (let item of scan({})) {
    console.log(`got ${await item}`);
    await sleep(1000);
  }
}

test();

Exekveringen stoppar inte för mig, oavsett hur många iterationer jag tilldelar inom scan.

Så det är alltså inte sleep som orsakar problemet, du borde titta någon annanstans. Kanske är problemet med mapper.scan, eller med de där HTTP-förfrågningarna, eller kanske behöver du bara uppgradera din Node.js (jag använder v10.11.0).