Javascript 具有收益承诺的生成函数.all()
我想分块运行一个函数,这样它将等待10k承诺解析,然后继续,我使用以下生成器函数:Javascript 具有收益承诺的生成函数.all(),javascript,asynchronous,ecmascript-6,generator,Javascript,Asynchronous,Ecmascript 6,Generator,我想分块运行一个函数,这样它将等待10k承诺解析,然后继续,我使用以下生成器函数: function* processNodes(nodes, task){ let i; let cnt = 0; let promiseArray = new Array(10000); let pInd = 0; let currId; for(i = 0; i<nodes.length; i++){ currId = nodes[i];
function* processNodes(nodes, task){
let i;
let cnt = 0;
let promiseArray = new Array(10000);
let pInd = 0;
let currId;
for(i = 0; i<nodes.length; i++){
currId = nodes[i];
promiseArray[pInd++] = asyncFunc(currId, 0, task); // return a promise
cnt++;
if(cnt > 10000){
console.log("going to yield", promiseArray)
let pall = Promise.all(promiseArray);
console.log("promise all", pall);
yield pall;
console.log("return from yield"); // never get here
pInd = cnt = 0;
}
}
}
您的问题是,您没有按应有的方式使用生成器功能。您永远无法访问
console.log('returnfromfield')
,因为在yield
,代码在yield语句之后停止执行。只有再次调用迭代器时,迭代器才会在yield语句之后继续(直到下一个yield语句)
因此,生成器创建一个迭代器,该迭代器具有一个值和一个bool标志done
。只要done未设置为true,就可以/应该再次调用下一个函数
代码的简化版本可以如下所示
//一个非常基本的异步函数,每5毫秒输出一个参数
函数asyncFunc(arg){
返回新承诺(函数(解析){
设置超时(()=>{
控制台日志(arg);
解决();
}, 5);
});
}
//发电机
函数*生成器(进程节点、任务){
风险限额=4,
队列=[];
for(设i=0;i=限制){
屈服承诺。全部(队列);
//推送后清除队列
log('after queue');
队列=[];
}
}
//确保接收方获得完整队列:)
if(queue.length!==0){
屈服承诺。全部(队列);
}
}
函数runthroughguments(参数、任务){
返回新承诺(函数(解析){
设置超时(()=>{
var节点=生成器(参数、任务),
迭代器=nodes.next();
如果(!iterator.done){
//如果不这样做,我们必须回忆起功能
iterator.value.then(函数q(){
设置超时(()=>{
迭代器=nodes.next();
if(!iterator.done&&iterator.value){
//调用命名函数(在本例中称为q),该函数是承诺完成后的函数
迭代器.value.then(q);
}否则{
//一切都结束了,所有的承诺都实现了
解决();
}
}, 2);
});
}否则{
iterator.value.then(解析);
}
}, 2);
});
}
贯穿件(
[‘嘿’、‘你’、‘岩石’、‘稳定’、‘船员’],
然后(()=>console.log('completed');
log('在一切之前运行')代码>您可以显示用于测试此函数的代码吗yield
将暂停函数,直到调用方使用该值。此:console.log(“从yield返回”);//never get here
@trincotI不是指代码,而是调用函数的主代码。它太大了,无法包含在这里@trincotI不确定我是否理解您的用例:首先,您创建了10000个承诺。然后你的收益率
,首先是10000个承诺,然后是10'001、10'002等等…
let x = processNodes(allNodes, someSimpleTask);
x.next();