Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Node.js中JavaScript/TypeScript中的异步/等待控制流

Node.js中JavaScript/TypeScript中的异步/等待控制流
EN

Stack Overflow用户
提问于 2020-07-29 14:33:41
回答 1查看 776关注 0票数 4

上下文:我试图在TypeScript中实现一个基本的套接字池。我当前的实现只是一个套接字的列表,其中有一个“可用/占用”枚举(不可否认,它可能是一个布尔值),它允许我有一个互斥机制,以确保每个套接字一次只发送/接收一个消息。

我所理解的是:我知道Node.js处理“并行”操作的方式是“单线程异步”。

我推断:对我来说,这意味着一次只有一个“控制指针”/“代码读头”/“控制流位置”,因为只有一个线程。在我看来,当“等待”被调用时,readhead只会跳转到代码中的其他地方,而我“等待”的承诺还无法解决。但我不知道情况是否真的如此。

我想知道的是:“单线程异步”是否确保除了调用“等待”之外,在任何时间都不会跳转控制流位置?或者是否有一些潜在的调度程序确实会在任意时刻导致任务之间的跳转,比如正常的多线程处理?

我的问题:所有这些都要问,我是否需要一个纯互斥/比较和交换机制来确保我的互斥类可用/占用字段被适当设置?

考虑以下代码:

代码语言:javascript
运行
AI代码解释
复制
export enum TaskSocketStatus
{
    AVAILABLE,  //Alive and available
    OCCUPIED,   //Alive and running a task
}

export interface TaskSocket
{
    status:TaskSocketStatus;
    socket:CustomSocket;
}


export class Server //A gateway that acts like a client manager for an app needing to connect to another secure server
{
    private sockets:TaskSocket[];

    [...]

    private async Borrow_Socket():Promise<TaskSocket|null>
    {
        for (const socket of this.sockets)
        {
            if (!socket.socket.Is_Connected())
            {
                await this.Socket_Close(socket);
                continue;
            }
            if (socket.status === TaskSocketStatus.AVAILABLE)
            {
//This line is where things could go wrong if the control flow jumped to another task;
//ie, where I'd need a mutex or compare-and-swap before setting the status
                socket.status = TaskSocketStatus.OCCUPIED;
                return (socket);
            }
        }
        if (this.sockets.length < this.max_sockets)
        {
            const maybe_socket = await this.Socket_Create();
            if (maybe_socket.isError())
            {
                return null;
            }
 //Probably here as well
            maybe_socket.value.status = TaskSocketStatus.OCCUPIED;
            return maybe_socket.value;
        }
        return null;
    }

    [...]
 }

我希望避免的问题是,由于竞争条件,两个不同的"SendMessage“任务借用相同的套接字。也许这是不必要的担心,但我想确保,因为这是一个潜在的问题,我真的不想面对当服务器已经在生产……

谢谢你的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-29 15:29:22

因此,当调用await时,另一个操作的控制流不是。当运行的Javascript片段返回到event循环时,event循环可以为下一个等待事件提供服务。已解析的承诺也可以通过事件循环工作(一个特殊的队列,但仍然在事件循环中)。

所以,当你点击await时,它不会立即跳转到其他地方。它将暂停该函数的进一步执行,然后导致该函数立即返回一个承诺,并且控制将继续,并将一个承诺返回给该函数的调用方。调用方的代码在收到承诺后继续执行。只有当调用方或调用方的调用方或调用方的调用方(取决于调用堆栈的深度)从启动整个执行链的事件循环返回到事件循环时,事件循环才有机会为下一个事件提供服务并启动新的执行链。

稍后,当连接到原始await的底层异步操作完成时,它将将一个事件插入到事件队列中。当其他Javascript执行将控制权返回到事件循环,而该事件到达事件队列的开始时,它将被执行,并将解析await等待的承诺。只有这样,在await有机会运行之后,函数中的代码才会运行。当包含该async函数的await最终完成它的内部执行时,那么最初在第一个await被击中时从async函数返回的承诺将被解析,并将通知调用者它得到的承诺已经解决(假设它在这个承诺上使用了await.then() )。

所以,从一个地方跳到另一个地方是不可能的。Javascript执行的当前线程将控制返回到事件循环(通过返回和展开其调用堆栈),然后事件循环可以为下一个等待事件服务,并启动一个新的执行链。只有当执行链完成并返回时,事件循环才能得到下一个事件并启动另一个执行链。以这种方式,只有一个调用堆栈帧一次运行。

在您的代码中,我不太理解您关心的内容。在Javascript中没有先发制人的转换。如果您的函数执行了await,那么它的执行将在此时暂停,其他代码可以在承诺得到解决之前运行,并在await之后继续执行。但是,没有先发制人的切换可以改变上下文并在这个线程中运行其他代码,而不需要调用一些异步操作,然后继续进行完整的回调或await之后。

因此,从纯Javascript的角度来看,不涉及异步操作的纯本地Javascript语句之间并不存在任何问题。这些代码保证是连续的、不间断的(我们假设您的代码中没有使用共享内存和工作线程的代码--在您发布的代码中没有任何迹象)。

我想知道的是:“单线程异步”是否确保除了调用“等待”之外,在任何时间都不会跳转控制流位置?

它确保控制流位置在任何时候都不会跳转,除非您返回事件循环(解除调用堆栈)。它不发生在awaitawait可能导致函数返回,并可能导致调用方返回到事件循环,同时等待返回的承诺解析,但重要的是要了解,只有当堆栈展开并将控制返回到事件循环时,才会发生控制流更改,以便可以从事件队列中提取下一个事件并进行处理。

还是有一些潜在的调度程序确实会在任意时刻导致任务之间的跳转,比如正常的多线程处理?

假设我们不是在讨论Worker,nodejs中没有先发制人的Javascript线程切换。只有当Javascript的当前线程返回回事件循环时,对另一段Javascript的执行才会发生更改。

我的问题:所有这些都要问,我是否需要一个纯互斥/比较和交换机制来确保我的互斥类可用/占用字段被适当设置?

不,你不需要互斥。在测试和set之间不返回事件循环,因此它们不会被任何其他代码中断。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63163441

复制
相关文章
python pandas读取csv文件_pandas将数据写入csv
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/175441.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/27
6.1K0
python pandas读取csv文件_pandas将数据写入csv
解析不规则csv文件文件帮助类
public class SplitHelper { /// <summary> /// 拓展分割 /// </summary> /// <param name="StrOneCsv">传入csv字符串</param> /// <returns></returns> public string[] ExpandSplit(string StrOneCsv) { StrOneCsv += ","; ArrayList ar
opengps
2018/04/13
1K0
将DataTable转换成CSV文件
该文介绍了如何将DataTable转换成CSV文件的方法,包括使用C#和StreamWriter等工具。
彭泽0902
2018/01/04
1.5K0
使用Java Scanner类解析CSV文件
如果你查看Scanner的API,你会发现该类支持文件和输入流作为输入方式,本例中我们采用文件的方式。
明明如月学长
2021/08/27
1.2K0
python爬虫将数据写入csv文件乱码
养成习惯,先赞后看!!! 出现乱码根本原因就是编码方式不对,但是博主自己尝试了三种编码方式终于找到了最合适的。
萌萌哒的瓤瓤
2020/08/26
4K0
python爬虫将数据写入csv文件乱码
Python 将数据写入文件(txt、csv、excel)
一、将列表数据写入txt、csv、excel 1、写入txt def text_save(filename, data):#filename为写入CSV文件的路径,data为要写入数据列表. file = open(filename,'a') for i in range(len(data)): s = str(data[i]).replace('[','').replace(']','')#去除[],这两行按数据不同,可以选择 s = s.replace
菲宇
2019/07/31
41.4K0
将Python网络爬虫的数据追加到csv文件
前几天在Python白银交流群有个叫【邓旺】的粉丝问了一个将Python网络爬虫的数据追加到csv文件的问题,这里拿出来给大家分享下,一起学习下。
前端皮皮
2022/08/17
2K0
将Python网络爬虫的数据追加到csv文件
支持各种特殊字符的 CSV 解析类 (.net 实现)(C#读写CSV文件)
csv(Comma Separated Values)逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。纯文本意味着该文件是一个字符序列,不含必须象二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。CSV是一种Excel表格的导出格式,在Excel表格的菜单栏中点击文件->另存为会弹出一个文件夹浏览窗口,在下拉框中可以选择保存格式,其中有一个就是.CSV(逗号分隔符)选项。 CSV是一种通用的、相对简单的文件格式,被用户、商业和科学广泛应用。最广泛的应用是在程序之间转移表格数据。因为大量程序都支持某种CSV变体,至少是作为一种可选择的输入/输出格式。例如,一个用户可能需要交换信息,从一个以私有格式存储数据的数据库程序,到一个数据格式完全不同的电子表格。最可能的情况是,该数据库程序可以导出数据为“CSV”,然后被导出的CSV文件可以被电子表格程序导入。 “CSV”并不是一种单一的、定义明确的格式(尽管RFC 4180有一个被通常使用的定义)。因此在实践中,术语“CSV”泛指具有以下特征的任何文件:
lulianqi
2018/08/30
3.3K0
【python】读取csv xlsx xlx txt文件 类
只需修改path class Reader: """ 可读取的文件格式: .csv .tsv .xlsx .xlx .txt """ @staticmethod def change_1d_array(array, header_cut=None, str_to_float=None): """ 为一维数组去掉第一个值;将字符串转为数值 :param array: type:<class 'numpy.ndarray'
司六米希
2022/11/15
1.1K0
利用脑记录产生的合成语音
这项研究是由语音科学家GopalaAnumanchipalli和Chang实验室的生物工程研究生Josh Chartier领导。该项研究是基于一系列研究基础上进行研究的,首次描述了人类大脑的语音中心是如何编排嘴唇,下巴,舌头,和其他声道组件的运动以生产流利的语音。
脑机接口社区
2020/07/01
5130
利用脑记录产生的合成语音
如何将多个csv文件合并到一个csv中
1、将所有的csv文件放到一个文件夹,比如D:/test中有a.csv,b.csv,c.csv,d.csv,f.csv
ytkah
2020/06/10
12K0
如何将多个csv文件合并到一个csv中
Java工具集-Csv文件读取工具类
添加依赖 <!--开源的opencsv--> <dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>4.6</version> </dependency> 代码示例 import java.io.FileInputStream; import java.io.FileNot
cwl_java
2020/05/01
2K0
利用Python批量将csv文件转化成xml文件
将 csv 格式转换成xml格式有许多方法,可以用数据库的方式,也有许多软件可以将 csv 转换成xml。但是比较麻烦,本文利用 Python 一键批量将 csv 文件转化成 xml 文件。
叶庭云
2021/12/01
1.7K0
利用Python批量将csv文件转化成xml文件
将文件夹中的文件信息统计写入到csv中
今天在整理一些资料,将图片的名字信息保存到表格中,由于数据有些多所以就写了一个小程序用来自动将相应的文件夹下的文件名字信息全部写入到csv文件中,一秒钟搞定文件信息的保存,省时省力!
小海怪的互联网
2019/09/18
9.3K0
CSV文件
CSV文件:Comma-Separated Values,中文叫,逗号分隔值或者字符分割值,其文件以纯文本的形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分割。每条记录由字段组成,字段间的分隔符是其他字符或者字符串。所有的记录都有完全相同的字段序列,相当于一个结构化表的纯文本形式。 用文本文件、EXcel或者类似与文本文件的都可以打开CSV文件。
狼啸风云
2020/02/11
2.6K0
使用python将csv文件快速转存到mysql
因为一些工作需要,我们经常会做一些数据持久化的事情,例如将临时数据存到文件里,又或者是存到数据库里。
我被狗咬了
2019/09/23
6.3K0
使用python将csv文件快速转存到mysql
python 读取单文件夹中的图片文件信息保存到csv文件中
# -*- coding: utf-8 -*- # @Time : 2019-09-17 10:21 # @Author : scyllake import os import csv #要读取的文件的根目录 root_path=r'C:\Users\zjk\Desktop\整理后的图片' #将所有目录下的文件信息放到列表中 def get_Write_file_infos(path): # 文件信息列表 file_infos_list=[] # 遍历并写入文件信息
小海怪的互联网
2019/10/14
5.7K0
基础知识 | 使用 Python 将数据写到 CSV 文件
我们从网上爬取数据,最后一步会考虑如何存储数据。如果数据量不大,往往不会选择存储到数据库,而是选择存储到文件中,例如文本文件、CSV 文件、xls 文件等。因为文件具备携带方便、查阅直观。
猴哥yuri
2018/08/16
1.9K0
点击加载更多

相似问题

Javascript在Internet Explorer中的行为很有趣

32

包含xml/html数据的jquery在internet explorer中的行为有所不同。

10

Div标记在Internet Explorer上的行为有所不同

11

javascript在internet explorer中的调试

21

Internet Explorer中的jScrollPane奇怪行为

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文