私は新しい非同期機能を使用しようとしています、そして私の問題を解決することが将来他の人に役立つことを願っています。これは私が働いているコードです:
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ループの実行が速すぎ、スクリプトが1秒あたりに送信するリクエストがgoogle APIに送信しすぎることです。そのため、リクエストを遅らせるスリープ機能を構築したいと思います。したがって、この機能を使って他のリクエストを遅らせることもできます。リクエストを遅らせる別の方法がある場合は、教えてください。
とにかく、これは機能しない私の新しいコードです。リクエストのレスポンスは、setTimeout内の無名の非同期関数に返されますが、どのようにしてレスポンスをsleep関数に返すことができるのかわかりません。最初の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関数から返す、無名関数内でのコールバックなどです。
sleep
はsetTimeout
される可能性のある約束を(まだ)返していないため、await
関数は機能しません。手動で確認する必要があります。
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
await timeout(3000);
return fn(...args);
}
ところで、ループを遅くするためには、コールバックを受けてこのように延期するsleep
関数を使用したくないでしょう。私はむしろ何かのようにすることをお勧めします
while (goOn) {
// other code
var [parents] = await Promise.all([
listFiles(nextPageToken).then(requestParents),
timeout(5000)
]);
// other code
}
これはparents
の計算に少なくとも5秒かかるようにします。
ノード7.6 以降、utilsモジュールの関数promisify
をsetTimeout()
と組み合わせることができます。
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(r => setTimeout(r, 1000))
クイックワンライナー、インライン方式
await new Promise(resolve => setTimeout(resolve, 1000));
setTimeout
はasync
関数ではないため、ES7 async-awaitでは使用できません。しかし、ES6を使ってsleep
関数を実装することができます Promise :
function sleep (fn, par) {
return new Promise((resolve) => {
// wait 3s before calling fn(par)
setTimeout(() => resolve(fn(par)), 3000)
})
}
そうすれば、ES7でこの新しいsleep
関数をasync-awaitで使用できるようになります。
var fileList = await sleep(listFiles, nextPageToken)
注意してください 私はES7 async/awaitを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
これは、ワンライナーでの迅速な修正です。
これが役立つことを願っています。
// WAIT FOR 200 MILISECONDS TO GET DATA //
await setTimeout(()=>{}, 200);
次のコードは、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..."
の構文エラーが発生します