简体   繁体   中英

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();
}

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();
}
private features : FeatureObject[] = [];

getFeaturesFromStream(): Promise<void> {
    const url = 'http://localhost:19100/api/v1/fetch?cgid=22&north=6853000.0&east=24505000&south=6850000.0&west=24500000.0';
    var self = this;
    return 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> {
    await getFeaturesFromStream();
    codeNotTobeCalledBeforeArrayReady();
}

I think all we need to do is return the promise you're waiting on, since you only care about the 'end' and that's the last link in that promise chain, you can just return that whole promise chain. Then you just wait for that promise to resolve in the caller which will ensure the codeNot... function is only called after the promise chain resolves

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM