angulartypescriptasync-awaitoboe.js

How to make typescript stream reading code not to proceed before stream is ended?


This is more general question but I just couldn't write it in more general way so I had to use the example I'm dealing with.

Anyway I looked into async+await, but it seems that Promise with resolve arrow function cannot be used with this example. So is it possible to refactor this function and calling code in a way that code after the call to getFeaturesFromStream is not called before on('end') code is called?

private features : FeatureObject[] = [];

getFeaturesFromStream() {
    const url = 'http://localhost:19100/api/v1/fetch?cgid=22&north=6853000.0&east=24505000&south=6850000.0&west=24500000.0';
    var self = this;
    oboe(url)
    .node('!', (row) => {
        console.log(row);
        self.features.push(row);
    })
    .on('end', () => {
        console.log('only after this we can proceed');
    });
}

async getFeatures() : Promise<void> {
    getFeaturesFromStream();
    codeNotTobeCalledBeforeArrayReady();
}

Solution

  • So it turned out that the promise works just like I thought. So yes, just add a promise and resolve it in correct place. Note that there's no error handling (fail + reject) and that unlike the question, this answer adds features in local variable features that is returned in the promise.

    async getFeaturesFromStream() : Promise<MyFeature[]> {
        return new Promise<MyFeature[]>((resolve) => {
            const features: MyFeature[] = [];
            const url = 'http://localhost:19100/pn/api/v1/fetch?cgid=22&north=6822169.0&east=24487155.0&south=6821411.0&west=24485674.0';
                oboe(url)
                .node('!', (row) => {
                    console.log(row);
                    features.push(row);
                })
                .on('end', () => {
                    console.log('only after this we can proceed. nbr of items' + features.length);
                    resolve(features);
                });
            });         
    }
    
    async getFeatures() : Promise<void> {
        const features = await getFeaturesFromStream();
        codeNotTobeCalledBeforeArrayReady();
    }