Programing

비동기 기능의 조합 + 대기 + setTimeout

lottogame 2020. 5. 8. 08:12
반응형

비동기 기능의 조합 + 대기 + setTimeout


새로운 비동기 기능을 사용하려고하는데 앞으로 문제를 해결하면 다른 사람들에게 도움이되기를 바랍니다. 이것은 작동하는 코드입니다.

  async function asyncGenerator() {
    // other code
    while (goOn) {
      // other code
      var fileList = await listFiles(nextPageToken);
      var parents = await requestParents(fileList);
      // other code
    }
    // other code
  }

  function listFiles(token) {
    return gapi.client.drive.files.list({
      'maxResults': sizeResults,
      'pageToken': token,
      'q': query
    });
  }

문제는 내 while 루프가 너무 빨리 실행되고 스크립트가 초당 너무 많은 요청을 Google API로 보냅니다. 따라서 요청을 지연시키는 절전 기능을 만들고 싶습니다. 따라서이 함수를 사용하여 다른 요청을 지연시킬 수도 있습니다. 요청을 지연시키는 다른 방법이 있으면 알려주십시오.

어쨌든, 이것은 작동하지 않는 새로운 코드입니다. 요청의 응답은 setTimeout 내에서 익명의 비동기 함수로 반환되지만 슬립 함수 resp에 응답을 반환하는 방법을 모르겠습니다. 초기 asyncGenerator 함수에.

  async function asyncGenerator() {
    // other code
    while (goOn) {
      // other code
      var fileList = await sleep(listFiles, nextPageToken);
      var parents = await requestParents(fileList);
      // other code
    }
    // other code
  }

  function listFiles(token) {
    return gapi.client.drive.files.list({
      'maxResults': sizeResults,
      'pageToken': token,
      'q': query
    });
  }

  async function sleep(fn, par) {
    return await setTimeout(async function() {
      await fn(par);
    }, 3000, fn, par);
  }

나는 이미 전역 변수에 응답을 저장하고 수면 함수, 익명 함수 내 콜백 등에서 응답을 저장하는 몇 가지 옵션을 시도했습니다.


당신의 sleep기능은 작동 setTimeout하지 않습니다 await. 수동으로 약속해야합니다.

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
    await timeout(3000);
    return fn(...args);
}

Btw, 루프 속도를 늦추려면 sleep콜백을 가져 와서 이것을 연기 하는 함수 를 사용하고 싶지 않을 것입니다 . 차라리 뭔가를하는 것이 좋습니다

while (goOn) {
  // other code
  var [parents] = await Promise.all([
      listFiles(nextPageToken).then(requestParents),
      timeout(5000)
  ]);
  // other code
}

계산 parents에 최소 5 초가 걸립니다.


Node 7.6부터는promisify utils 모듈 의 함수 기능을와 결합 할 수 있습니다 setTimeout().

Node.js

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

자바 스크립트

const sleep = m => new Promise(r => setTimeout(r, m))

용법

(async () => {
    console.time("Slept for")
    await sleep(3000)
    console.timeEnd("Slept for")
})()

빠른 한 줄짜리 인라인 방식

 await new Promise(resolve => setTimeout(resolve, 1000));

setTimeout is not an async function, so you can't use it with ES7 async-await. But you could implement your sleep function using ES6 Promise:

function sleep (fn, par) {
  return new Promise((resolve) => {
    // wait 3s before calling fn(par)
    setTimeout(() => resolve(fn(par)), 3000)
  })
}

Then you'll be able to use this new sleep function with ES7 async-await:

var fileList = await sleep(listFiles, nextPageToken)

Please, note that I'm only answering your question about combining ES7 async/await with setTimeout, though it may not help solve your problem with sending too many requests per second.


Update: Modern node.js versions has a buid-in async timeout implementation, accessible via util.promisify helper:

const {promisify} = require('util');
const setTimeoutAsync = promisify(setTimeout);

If you would like to use the same kind of syntax as setTimeout you can write a helper function like this:

const setAsyncTimeout = (cb, timeout = 0) => new Promise(resolve => {
    setTimeout(() => {
        cb();
        resolve();
    }, timeout);
});

You can then call it like so:

const doStuffAsync = async () => {
    await setAsyncTimeout(() => {
        // Do stuff
    }, 1000);

    await setAsyncTimeout(() => {
        // Do more stuff
    }, 500);

    await setAsyncTimeout(() => {
        // Do even more stuff
    }, 2000);
};

doStuffAsync();

I made a gist: https://gist.github.com/DaveBitter/f44889a2a52ad16b6a5129c39444bb57


The following code works in Chrome and Firefox and maybe other browsers.

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
    await timeout(3000);
    return fn(...args);
}

But in Internet Explorer I get a Syntax Error for the "(resolve **=>** setTimeout..."


var testAwait = function () {
    var promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Inside test await');
        }, 1000);
    });
    return promise;
}

var asyncFunction = async function() {
    await testAwait().then((data) => {
        console.log(data);
    })
    return 'hello asyncFunction';
}

asyncFunction().then((data) => {
    console.log(data);
});

//Inside test await
//hello asyncFunction

This is a quicker fix in one-liner.

Hope this will help.

// WAIT FOR 200 MILISECONDS TO GET DATA //
await setTimeout(()=>{}, 200);

참고URL : https://stackoverflow.com/questions/33289726/combination-of-async-function-await-settimeout

반응형