[javascript] 비동기 기능 조합 + 대기 + 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));


답변

setTimeoutasync기능 이 아니므 로 ES7 async-await와 함께 사용할 수 없습니다. 그러나 sleepES6 Promise를 사용 하여 함수를 구현할 수 있습니다 .

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

그런 다음 sleepES7 async-await 에서이 새로운 기능 을 사용할 수 있습니다.

var fileList = await sleep(listFiles, nextPageToken)

, 참고하시기 바랍니다 난 단지 ES7 비동기 / await를 가진 결합에 대한 귀하의 질문에 대답 해요 있다는 setTimeout것이 도움이 초당 너무 많은 요청을 전송하여 문제를 해결할 수 있지만,.


업데이트 : 최신 node.js 버전에는 util.promisify 도우미 를 통해 액세스 할 수있는 buid-in 비동기 시간 초과 구현이 있습니다 .

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


답변

같은 종류의 구문을 사용하려면 다음과 같은 setTimeout도우미 함수를 작성할 수 있습니다.

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

그런 다음 다음과 같이 호출 할 수 있습니다.

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

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

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

doStuffAsync();

나는 요지를 만들었다 : https://gist.github.com/DaveBitter/f44889a2a52ad16b6a5129c39444bb57


답변

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


답변

다음 코드는 Chrome 및 Firefox 및 다른 브라우저에서 작동합니다.

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

그러나 Internet Explorer에서에 대한 구문 오류가 발생합니다. "(resolve **=>** setTimeout..."