Pipes are asynchronous in Windows cmd.exe. They do not wait for the left side to complete before passing the info to the right. But your program does not demonstrate that for two reasons.
1) The FOR /F command does not begin iterating any rows until the command within the IN() clause completes. This is true for all FOR /F variants. The entire result of the IN() clause is buffered before any rows are iterated.
So your filter.bat couldn't possibly demonstrate the asynchronous nature of pipes.
2) The MORE command will not write partial lines - it waits until it receives a newline character before printing to stdout. (unless it reaches the end of file).
If you want to truly see the asynchronous nature of pipes, it is better to use a program that reads each character from stdin and immediately writes it back out to stdout.
Here is my version of FEED.BAT - it writes multiple lines with multiple pauses. It also writes three characters without linefeed with a pause after each one.
@echo off
echo something
timeout /nobreak 3 >nul
echo something else
timeout /nobreak 3 >nul
for /l %%N in (1 1 3) do (
<nul set /p "=%%N"
timeout /nobreak 3 >nul
)
echo(
echo Done
Here is my version of FILTER.JS - it reads one character from stdin and writes it out to stdout until it reaches the end of file.
while (!WScript.StdIn.AtEndOfStream) WScript.Stdout.Write(WScript.StdIn.Read(1));
And here is the command to test the behavior
feed | cscript //nologo filter.js
And here is the output, with <pause>
inserted whenever there is a pause before more output.
something
<pause>something else
1<pause>2<pause>3<pause>
Done
My test above demonstrates that a pipe will immediately send any information it receives (assuming the filter is ready to receive it).
Design of the feeder and/or filter may mask the free flowing behavior. Your original test had a bottleneck in the filter in that it waited for all input before proceeding. It is also possible for the feeder to hold things up. Some programs have buffered output. The feeder may not send data until the buffer is full, or the buffer is flushed, or the stream closed.
There are a number of peculiar behaviors associated with Windows pipes. I recommend reading all the answers to Why does delayed expansion fail when inside a piped block of code? for a good overview of many non-intuitive issues.