It derived from the usual philosphy of Arduino loop() should never be blocking, although your call to delay() will help the other task such Wifi to run, you won't be able to run other stuff in your own loop().
Let get back with my previous snippet of code :
void loop()
{
if (Serial.available()) {
int inByte = Serial.read();
Serial.write(inByte);
buf[i] = (char)inByte;
if (inByte == '\r' or inByte == '\n') {
buf[i] = 0;
i = 0;
Serial.print("echo = ");
Serial.println(buf);
if (strcmp(buf, "hello") == 0) {
Serial.println("Hello !");
}
else if (strcmp(buf, "showip") == 0) {
showIP(Serial);
}
}
else
i++;
}
// some other stuff to do in loop()
if (blink_count >= blink_rate) {
digitalWrite(led, HIGH);
blink_count = 0;
}
if (blink_count == blink_rate / 2) {
digitalWrite(led, LOW);
}
webserver.handleClient();
delay(1);
blink_count++;
}
You can see in the above code the last portion is doing additional tasks : First, a LED blink, even it you didn't have provide full line into your Serial transaction, LED still blink at a specific rate. Second, you add a webserver, but you wish that this server still provide responses even if your Serial transaction is not finished.
Hoping this giving you the idea about "pseudo-multithread" concept ...
Of course there are many other to do that, but the above is the Arduino concept.
BTW, for Serial handling, you can also look to SerialEvent (https://www.arduino.cc/en/Tutorial/SerialEvent) if you wish to fill the buffer as a background task, but still the main loop() will have to look at global flag.