A recent business scenario required a promise to be executed in a loop, with the result of the previous request being the parameter of the next request

A basic Promise

const moment = require( "moment" );
const current = moment( Date.now() ).format( "A:hh:mm:ss" );
const promise = ( item, params = current ) = > new Promise( ( resolve, reject ) = > {
  setTimeout( (a)= > {
    const d = moment( Date.now() ).format( "A:hh:mm:ss" );
    resolve( {
      req: params,
      rep: d,
      item
    } );
  }, 3000); });Copy the code

for+async/awaitversion


const forAsync = async ( arr ) => {
  let obj = {};
  for (let index = 0; index < arr.length; index ++) {
    obj = await promise( arr[ index ], obj.rep );
    console.log( obj ); }};Copy the code

Array.prototype.reduce+async/awaitversion


const reduceAsync = ( arr ) = > {
  arr.reduce( async ( prev, curr ) => {
    const { rep } = await prev;
    const obj = await promise( curr, rep );
    console.log( obj );
    return obj;
  }, Promise.resolve( {} ) );
};

Copy the code

Array.prototype.reduce+Promiseversion


const reducePromise = ( arr ) = > {
  arr.reduce( ( prev, curr ) = > {
    return prev.then( data= > {
      return new Promise( ( resolve, reject ) = > {
        promise( curr, data.rep ).then( res= > {
          console.log( res ); resolve( res ); }); }); }); },Promise.resolve( {} ) );
};

Copy the code

# Execution result
{ req: 'PM:04:49:08', rep: 'PM:04:49:11', item: 1 }
{ req: 'PM:04:49:11', rep: 'PM:04:49:14', item: 2 }
{ req: 'PM:04:49:14', rep: 'PM:04:49:17', item: 3 }
{ req: 'PM:04:49:17', rep: 'PM:04:49:20', item: 4 }

Copy the code

Array.prototype.map+Promiseversion


const mapPromise = ( arr ) = > {
  let temporary = Promise.resolve( {} );
  arr.map( ( item, index ) = > {
    temporary = temporary.then( ( data ) = > {
      if(i ! = =0) {
        // The first initial promise
        console.log( data );
      }
      returnpromise( item, data.rep ); }); });// Last promise
  temporary.then( data= > console.log( data ) );
};
Copy the code

With map traversal, the return value of the initial promise needs to be filtered, and after traversal, the last promise needs to be manually executed, otherwise the result will be the following


# Execution result
{}
{ req: 'PM:04:49:08', rep: 'PM:04:49:11', item: 1 }
{ req: 'PM:04:49:11', rep: 'PM:04:49:14', item: 2 }
{ req: 'PM:04:49:14', rep: 'PM:04:49:17', item: 3 }

Copy the code

The above results are obviously not what we need, but if we need to manually filter the first promise and execute the last promise, the unnecessary code amount and error rate will be increased and mapPromise will be modified as follows, the principle of which is similar to array.prototype. reduce+Promise version


const mapPromise = ( arr ) = > {
  let temporary = Promise.resolve( {} );
  arr.map( ( item, index ) = > {
    temporary = temporary.then( ( data ) = > {
      // if (i ! = = 0) {
      // // The first promise
      // console.log( data );
      // }
      return new Promise( ( resolve, reject ) = > {
        promise( item, data.rep ).then( data= > {
          console.log( data ); resolve( data ); }); }); }); });// Last promise
  // temporary.then( d => console.log( d ) );
};

Copy the code

other

Array.prototype.map = array.prototype. map = array.prototype. map = array.prototype. map = array.prototype. map = array.prototype. map = array.prototype. map I don’t want to repeat it