Saying ON SOCKOPEN or ON SOCKWRITE are triggered in response to /sockopen or /sockwrite is equivalent to saying that ON TEXT is triggered by //msg $me hello. In both cases events occur outside the scope of mIRC with unpredictable delay. Just because /sockopen or /sockwrite started a chain of events doesn't mean that no external stimuli were involved at a later point.
No, there is an important difference here: mIRC will *always* trigger ON SOCKOPEN. An "unpredictable delay" does not mean it's not triggered by you. It may not always come within X ms, but it is guaranteed to be triggered. You can get an unpredictable delay from many events that you trigger, /dns being the first example that comes to mind. And yet, /dns is guaranteed to trigger ON DNS in the same way ON SOCKOPEN is guaranteed to be triggered by /sockopen, regardless of the delay.
This is very much unlike ON TEXT for a few reasons. First, ON TEXT is specifically in response to the server sending you a message, which means there is no guarantee that message will ever be sent. No, //msg $me hello does not guarantee an ON TEXT event will trigger. You must be connected, the server must allow that command, etc. Only at this point is another external "entity" making a decision about what you will receive.
ON SOCKOPEN does not go through any external entity to get the data necessary to trigger the event. It is an inherent part of the control flow of /sockopen. You can think of /sockopen as being implemented by the following pseudo-code:
MIRC_SOCKET_STRUCT *socket = create_socket();
/* read in arguments */
socket->fd = connect(socket->fd, socket->hostname, sizeof(hostname));
socket->err = WSAGetLastError();
I used a blocking call to connect(), which mIRC may or may not be doing, but one thing is being done by both implementations: the event is triggered after connect() finishes, regardless of whether the connection was successful. In this sense, and certainly if you look at the pseudo-code above, the ON SOCKOPEN event is a direct
result of the /sockopen command. Sure, connect() blocks for an indefinite amount of time, but that doesn't make the event any less direct a result of the command.