0
    processUpdate() {
        const {number} = this.props;

        Promise.all([
            getList('PDF'),
            getName()
        ]).then(([list, name]) => {

            this.setState({list, name});
        }).catch((error) => {

            ErrorService.setPageError('Eeerr');
            throw error;
        });
    }

getList('PDF') api call returns an empty array for 2-3 minutes. After some time list gets ready on the server then server returns an array. I need to loop getList('PDF') call in every 10 seconds till the response is not empty.

I would like to do it in Promise.all, is that possible? Thanks

serkan
  • 6,885
  • 4
  • 41
  • 49
  • Call `getList('PDF')` inside itself with a `setTimeout` of 10 seconds maybe? You'd also need to always return the new call though, so `Promise.all` still resolves when you finally get the desired status. – Sergiu Paraschiv Feb 28 '19 at 14:53
  • Then it would pass to `this.setState({list, name});` with empty array. That is exactly that i am trying to prevent. Am i wrong? – serkan Feb 28 '19 at 14:54
  • 1
    Exactly, that's why instead of resolving with an empty list you resolve with a new promise returned by a new `getList('PDF')` call. `Promise(Promise(Promise)).then` is only called when the inner most promise resolves. – Sergiu Paraschiv Feb 28 '19 at 14:56
  • The `this.setState({list, name});` code line makes me think that the code belongs to a React component. Is that the case? – Carlos Lombardi Feb 28 '19 at 14:59
  • @SergiuParaschiv That makes sense. Thing is, the function is kind of generic. I need to create another function that resolves depending on the data rather than status code which i am not willing to, honestly. – serkan Feb 28 '19 at 15:12
  • @CarlosLombardi, yes, unfortunately. – serkan Feb 28 '19 at 15:13
  • Then why not return a different status code while the final response is not ready? – Sergiu Paraschiv Feb 28 '19 at 15:15
  • I do not have access to backend. Stupid but it is what it is. – serkan Feb 28 '19 at 15:16
  • 1
    Then @Bergi's answer is what you need to do. – Sergiu Paraschiv Feb 28 '19 at 15:16

2 Answers2

1

No, you shouldn't do it within the Promise.all, that has nothing to do with it. You just need a recursive approach that polls until the result is not empty any more:

function getListResult(id) {
    return getList(id).then(result => result.length ? result : getListResult(id));
}

processUpdate() {
    return Promise.all([
        getListResult('PDF'),
//             ^^^^^^
        getName()
    ]).then(([list, name]) => {
        this.setState({list, name});
    }, error => {
        ErrorService.setPageError('Eeerr');
        throw error;
    });
}

Btw, don't forget to return the promise from your method if you reject it by rethrowing the error.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks Bergi, where should put the timer to do this in every 10 seconds? In the result function or Promise.all? Can not get my head around it. – serkan Feb 28 '19 at 15:22
  • You mean you don't want to do the retry immediately? You'd then do a `delay(10e3).then(() => getListResult(id))` in the result function - as I said the `Promise.all` has nothing to do with this. – Bergi Feb 28 '19 at 15:29
1

I don't know how much control you have over your system's architecture, but this is a good scenario for implementing web sockets, I strongly encourage that approach over client-side polling.

However, if you are looking for a quick fix, this simple code should help you:

processUpdate(id) {
    let pdfsPromise = new Promise(resolve => {
        var getPdfs = () => {
            return new Promise(resolve => {
                let pdfs = getList('PDF');
                if(pdfs && pdfs.length > 0) {
                    resolve(pdfs);
                }
                else {
                    setTimeout(() => {
                        getPdfs().then(resolve);
                    }, 10000)
                }
            })
        }
        getPdfs().then(resolve);
    });
    Promise.all([pdfsPromise, getName()]).then (([list, name]) => {
        this.setState({list, name});
    });
}

BTW I left out error handling for code simplicity

Ethan Melamed
  • 367
  • 1
  • 11
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Nov 28 '19 at 01:09