【发布时间】:2019-05-22 21:37:51
【问题描述】:
编辑:找到答案 - https://www.youtube.com/watch?v=8aGhZQkoFbQ
_
好的,所以我有一些 C# 背景,而 C#“异步环境”有点混合并发和“small parallelism”,即当涉及到繁重的异步环境时,您 可以 em> 存在竞争条件、死锁,您需要保护共享资源。
现在,我试图了解 JavaScript/ES6 异步环境是如何工作的。考虑以下代码:
// current context: background "page"
// independent from content page
let busy = false;
// This is an event handler that receives event from content page
// It can happen at any time
runtimeObj.onMessage.addListener((request) =>
{
if(request.action === 'AddEntry')
{
AddEntry(request);
return true;
}
return false;
} );
function AddEntry(data)
{
if (!busy)
group.push({url: data.url, time: Date.now(), session: data.session});
else
setTimeout(AddEntry(data),10000) // simulating Semaphore wait
}
// called from asynchronous function setInterval()
function SendPOST()
{
if (groups.length < 1 || groups === undefined)
return;
busy = true; // JS has no semaphores so I "simulate it"
let del = [];
groups.forEach(item =>
{
if (Date.now() - item.time > 3600000)
{
del.push(item);
let xhr = new XMLHttpRequest();
let data = new FormData();
data.append('action', 'leave');
data.append('sessionID', item.session);
xhr.withCredentials = true;
http.onreadystatechange = function()
{
if(http.readyState == 4 && http.status !== 200) {
console.log(`Unable to part group ${item.url}! Reason: ${http.status}. Leave group manually.`)
}
}
xhr.open('POST', item.url, true);
xhr.send(data);
}
});
del.forEach(item => groups.slice(item,1));
busy = false;
}
setInterval(SendPOST, 60000);
这并不是最好的例子,因为它没有一堆与函数配对的 async 关键字,但在我的理解中,sendPost() 和 AddEntry() 都不是真正的纯顺序操作。尽管如此,有人告诉我,在AddEntry() 中,busy 始终是false,因为:
sendPost 排队等待一分钟后执行
一个事件被添加到事件循环中
处理事件并调用 AddEntry
因为busy = false,组被推送
一分钟过去了,SendPost 被添加到事件循环中
事件正在处理,SendPost 被调用
groups.length === 1 所以它继续
忙 = 真
每个组都会导致一个请求排队
一个事件来了
忙 = 假
事件处理完毕,调用AddEntry
忙碌是假的,就像永远一样
群组被推送
最终,之前的请求得到了解决,并且 t 他将 onreadystatechange 回调放在事件循环中
最终处理每个回调并执行日志记录语句
这是正确的吗?据我了解,这基本上意味着不会出现竞争条件或死锁,或者我需要保护共享资源。
如果我是两个为 C# 运行时编写类似代码,其中 sendPost() 和 AddEntry() 是异步任务方法,可以从那里的不同事件源以非阻塞方式调用 可能当我访问共享资源时迭代上下文被线程调度器在上下文切换中暂时挂起。
【问题讨论】:
-
这个:这是正确的吗?据我了解,这本质上意味着不会出现竞争条件或死锁,或者我需要保护共享资源。 是的 - 它在 JavaScript 中称为“Run to Completion”。逻辑错误可能会产生竞争条件,开发人员希望在完成之前设置某些内容,但这是由于代码问题 - 而不是并发问题。
-
@RandyCasburn 是的,这就是我帖子中的
quoted text所解释的。 -
正如我所怀疑的,只是想确定一下。 @jonas 给你一个很好的答案。
-
你应该把这个:
groups.length < 1 || groups === undefined改成这个!groups || groups.length < 1前者可能会报错。
标签: javascript c# asynchronous concurrency