Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/465.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用JS/generator实现简单信号量_Javascript_Node.js_Promise_Generator_Semaphore - Fatal编程技术网

Javascript 使用JS/generator实现简单信号量

Javascript 使用JS/generator实现简单信号量,javascript,node.js,promise,generator,semaphore,Javascript,Node.js,Promise,Generator,Semaphore,我尝试使用NodeJS只允许两个任务同时访问一段代码(例如,可以访问一个API,但下面用yield wait(2000)模拟)。我正在使用co包使其与生成器和承诺一起工作,而不是回调,但是下面的代码一次只允许1而不是2访问承诺(sem)和sem.leave()之间的代码 信号量包是NodeJS-one(),它有一个take和leave函数来进入和离开受保护的代码部分 我正在尝试下面的ES6承诺 var sem = require('semaphore')(2); function wait(m

我尝试使用NodeJS只允许两个任务同时访问一段代码(例如,可以访问一个API,但下面用
yield wait(2000)模拟)
。我正在使用
co
包使其与生成器和承诺一起工作,而不是回调,但是下面的代码一次只允许1而不是2访问
承诺(sem)
sem.leave()
之间的代码

信号量包是NodeJS-one(),它有一个
take
leave
函数来进入和离开受保护的代码部分

我正在尝试下面的ES6承诺

var sem = require('semaphore')(2);

function wait(millis) {
    return new Promise(function(resolve, reject) {
        setTimeout(function(){resolve()}, millis);
    });
}

function semPromise(sem) {
    return new Promise(function(resolve, reject) {
        sem.take(function() {
            resolve();
        });
    });
}

co(function *main() {
    for (var i=0; i<10; ++i) {
        yield semPromise(sem);
        console.log('enter' + i);
        yield wait(2000);
        console.log('done' + i);
        sem.leave();
    }
});


这似乎是可行的。但如果我试图避免回调并学习如何正确使用承诺,我该怎么做呢?

这些代码片段之间存在巨大的差异;另一个代码片段并行触发10次超时,而生成器版本则等待1次超时完成,然后才开始下一次。在ord中使用生成器时需要小心呃,不要编写缓慢的顺序代码。生成器版本是如何运行的?难道
屈服等待(2000)
不异步运行吗?@user779159不,使用生成器的关键是
屈服等待(2000)
暂停生成器。与正常函数不同,生成器可以产生控制并有效地“暂停”虽然实际IO仍然是异步的。@user779159它异步运行,因为整个程序没有冻结,但显然它阻止了生成器
        yield wait(2000);
        console.log('done' + i);
        sem.leave();
        setTimeout(function() {
            console.log('done');
            sem.leave();
        }, 2000);