即使unconsumedBufferLength为0,DataReader.loadAsync也正在完成

Kag*_*ght 6 javascript windows-runtime typescript

我使用以下代码在UWP WinRT上使用JSON流:

async function connect() {
    let stream: MSStream;
    return new CancellableContext<void>(
        async (context) => {
            // this will be called immediately
            stream = await context.queue(() => getStreamByXHR()); // returns ms-stream object
            await consumeStream(stream);
        },
        {
            revert: () => {
                // this will be called when user cancels the task
                stream.msClose();
            }
        }
    ).feed();
}

async function consumeStream(stream: MSStream) {
    return new CancellableContext<void>(async (context) => {
        const input = stream.msDetachStream() as Windows.Storage.Streams.IInputStream;
        const reader = new Windows.Storage.Streams.DataReader(input);
        reader.inputStreamOptions = Windows.Storage.Streams.InputStreamOptions.partial;

        while (!context.canceled) {
            const content = await consumeString(1000);
            // ... some more codes
        }

        async function consumeString(count: number) {
            await reader.loadAsync(count); // will throw when the stream gets closed
            return reader.readString(reader.unconsumedBufferLength);
        }
    }).feed();
}
Run Code Online (Sandbox Code Playgroud)

这里的文件InputStreamOptions.partial说:

当一个或多个字节可用时,异步读取操作完成.

但是,reader.loadAsync即使reader.unconsumedBufferLength为0 也会完成,这会使CPU负载.这是一个API错误还是可以阻止此行为,以便loadAsync只有在unconsumedBufferLength大于0 时才能完成?

PS:这是一个纯JS的repro:https://github.com/SaschaNaz/InputStreamOptionsBugRepro

bas*_*rat 1

这是 API 错误还是我可以阻止此行为,以便 loadAsync 仅当 unconsumedBufferLength 大于 0 时才能完成

最有可能的是它也在流结束时完成。因此,在这种情况下,该值unconsumedBufferLength将为零并且需要得到满足。

事实上, https://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.datareader.aspx上的示例显示了类似的内容(诚然没有使用该选项):

            // Once we have written the contents successfully we load the stream.
            await dataReader.LoadAsync((uint)stream.Size);

            var receivedStrings = "";

            // Keep reading until we consume the complete stream.
            while (dataReader.UnconsumedBufferLength > 0)
Run Code Online (Sandbox Code Playgroud)