Javascript 异步函数的组合+;等待&x2B;设置超时
我正在尝试使用新的异步特性,我希望解决我的问题能在将来帮助其他人。这是我正在工作的代码:Javascript 异步函数的组合+;等待&x2B;设置超时,javascript,async-await,settimeout,ecmascript-2017,Javascript,Async Await,Settimeout,Ecmascript 2017,我正在尝试使用新的异步特性,我希望解决我的问题能在将来帮助其他人。这是我正在工作的代码: async function asyncGenerator() { // other code while (goOn) { // other code var fileList = await listFiles(nextPageToken); var parents = await requestParents(fileList); /
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循环运行得太快,脚本每秒向googleapi发送的请求太多。因此,我想构建一个延迟请求的睡眠函数。因此,我还可以使用此函数延迟其他请求。如果有其他方法延迟请求,请让我知道
无论如何,这是我的新代码,不起作用。请求的响应在setTimeout内返回给匿名异步函数,但我不知道如何将响应返回给sleep函数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
不是一个async
函数,因此不能将其与ES7 async wait一起使用。但是您可以使用ES6实现睡眠功能:
然后,您将能够在ES7 async await中使用此新的sleep
功能:
var fileList = await sleep(listFiles, nextPageToken)
请注意我只是回答您关于将ES7 async/await与setTimeout
相结合的问题,尽管这可能无助于解决您每秒发送太多请求的问题
更新:Modern node.js版本具有内置的异步超时实现,可通过帮助器访问:
您的sleep
功能不起作用,因为setTimeout
没有(尚未?)返回一个可以wait
ed的承诺。您需要手动承诺:
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
}
这使得父节点的计算至少需要5秒。自节点7.6以来,您可以将utils模块中的函数promisify
与setTimeout()
组合
Node.js
Javascript
用法
快速一行,直列方式
await new Promise(resolve => setTimeout(resolve, 1000));
如果要使用与setTimeout
相同的语法,可以编写如下帮助函数:
const setAsyncTimeout=(cb,timeout=0)=>新承诺(resolve=>{
设置超时(()=>{
cb();
解决();
},超时);
});
你可以这样称呼它:
const dostufasync=async()=>{
等待setAsyncTimeout(()=>{
//做事
}, 1000);
等待setAsyncTimeout(()=>{
//多做事
}, 500);
等待setAsyncTimeout(()=>{
//做更多的事情
}, 2000);
};
doStuffAsync();
我提出了一个要点:以下代码适用于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…”
这是一个更快的修复方法
希望这会有所帮助
// WAIT FOR 200 MILISECONDS TO GET DATA //
await setTimeout(()=>{}, 200);
制作了一个灵感来源于
基本上是在done
回调中传递,以便在操作完成时调用
//如果请求时间过长,函数将超时
const setAsyncTimeout=(cb,timeout=0)=>新承诺((解析,拒绝)=>{
cb(决议);
setTimeout(()=>reject('请求响应时间太长'),超时);
});
我就是这样使用它的:
试试看{
等待setAsyncTimeout(异步完成=>{
const requestOne=等待someService.post(配置);
const requestTwo=等待someService.get(配置);
const requestThree=等待someService.post(配置);
完成();
},5000);//这组操作最多5秒
}
捕捉(错误){
控制台。错误(“[Timeout]无法完成操作”,错误);
}
这是我的nodejs版本,现在是2020年在AWS labdas中的版本
const sleep = require('util').promisify(setTimeout)
async function f1 (some){
...
}
async function f2 (thing){
...
}
module.exports.someFunction = async event => {
...
await f1(some)
await sleep(5000)
await f2(thing)
...
}
如果您的节点版本为15或更高版本,则将正常工作。更新2021
wait setTimeout
最终与Node.js 16一起到达,不再需要使用util.promisify()
:
Official Node.js文档:(库已经内置在节点中)
wait new Promise(resolve=>setTimeout(()=>{resolve({data:'your return data'})},1000))
你不应该这样做,当fn
抛出错误时,错误将不会被捕获。@Bergi我认为它会出现在新承诺
中,在那里你可以睡眠。捕获它。@Dodekeract不,它处于异步设置超时
回调中,新承诺
回调已经做了很长时间。它将冒泡到全局上下文和将被作为未处理的异常抛出。>每秒发送太多请求的问题。您可能希望使用“debounce”来防止UI触发太多请求之类的事情。热爱承诺。所有方法。如此简单和优雅!var[parents]的符号是什么
representation?我以前没见过,很难理解google@NateUsher它是@tinkerr-Nope。一个函数只需要返回一个可以等待的承诺(或者实际上,一个thenable就足够了)。它如何实现这一点取决于函数的实现,它不需要是异步函数
@naisanza No,异步
/等待
是基于承诺的。它所替代的唯一东西是然后
调用。在nodeJS等待要求('util')。promisify(setTimeout)(3000)
也可以通过以下方式无需实现:等待setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](3000)
interest@Shl。但我认为它不如我的解决方案可读。如果有人不同意,我可以将其添加到解决方案中?所需版本显然比getOwnPropertySymbols
版本好得多…如果它没有损坏的话…!嘿@Harry。看来你在自己的答案中加入了来自FlavorScape答案的一行代码我
(async () => {
console.time("Slept for")
await sleep(3000)
console.timeEnd("Slept for")
})()
await new Promise(resolve => setTimeout(resolve, 1000));
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function sleep(fn, ...args) {
await timeout(3000);
return fn(...args);
}
// WAIT FOR 200 MILISECONDS TO GET DATA //
await setTimeout(()=>{}, 200);
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
const sleep = require('util').promisify(setTimeout)
async function f1 (some){
...
}
async function f2 (thing){
...
}
module.exports.someFunction = async event => {
...
await f1(some)
await sleep(5000)
await f2(thing)
...
}
await setTimeout(()=>{}, 200);
import { setTimeout } from 'timers/promises';
(async () => {
const result = await setTimeout(2000, 'resolved')
// Executed after 2 seconds
console.log(result); // "resolved"
})()