javascriptpromisesequencefetch-apichain

javascript promise chain with fetch not in sequence


I want to dynamically build a promise chain, that should do things in the background. Mainly it should do some output on the web page.

That works until I put promises from fetch into the chain. Those promises are not executed in the expected sequence.

The following example shows how the chain is build:

var chain = Promise.resolve();
for(var i = 0; i < actions.length; ++i)
  chain = actions[i].extendChain(chain);

function actionExample(chain) {
  return chain.then(...);
}

That works with direct output:

function actionOutput(chain) {
  return chain.then(new Promise(resolve => {
    print('text');
    resolve();
  }));
}

But fetch or is not in sequence:

function actionLoad(chain) {
  const url = '...';
  return chain.then(new Promise(() => print('run action load\n')))
    .then(() => fetch(url))
    .then((response) => response.json())
    .then(processResponse)
    .then(requestOutput)
    .then(receiveOutput);
}

The function requestOutput also contains a fetch, but already the call of processResponse is delayed.

What can I change so that all steps are executed in the wanted sequence?


Solution

  • There's absolutely no reason to create new promises here. Passing a Promise instance to .then() is also incorrect as it requires one or two functions.

    The .then() method always returns a new promise that resolves with the return value of the function provided

    function actionOutput(chain) {
      return chain.then(() => print('text'));
    }
    
    
    function actionLoad(chain) {
      const url = '...';
      return chain
        .then(() => print('run action load\n')) // resolves with return value of
                                                // `print()`, probably `undefined`
        .then(() => fetch(url))
        .then((response) => response.ok ? response.json() : Promise.reject(res))
        .then(processResponse)
        .then(requestOutput)
        .then(receiveOutput);
    }