如何在循環中串行執行promise

最近有個業務場景,須要在循環中執行promise,而且上一個請求的結果爲下一個請求的參數javascript

一個基本的Promisejava

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

複製代碼

for+async/await版本

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

複製代碼

Array.prototype.reduce+async/await版本

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

複製代碼

Array.prototype.reduce+Promise版本

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

複製代碼
# 執行結果
{ 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 }

複製代碼

Array.prototype.map+Promise版本

const mapPromise = ( arr ) => {
  let temporary = Promise.resolve( {} );
  arr.map( ( item, index ) => {
    temporary = temporary.then( ( data ) => {
      if (i !== 0) {
        // 第一個初始promise
        console.log( data );
      }
      return promise( item, data.rep );
    } );
  } );
  // 最後一個promise
  temporary.then( data => console.log( data ) );
};
複製代碼

map遍歷時,須要過濾初始promise的返回值,而且在遍歷結束後,需手動執行最後之後一個promise,不然就會變成以下結果promise

# 執行結果
{}
{ 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 }

複製代碼

以上結果明顯不是咱們所須要的,可是須要手動過濾第一個promise和執行最後一個promise,會增項沒必要要的代碼量和出錯率 後將mapPromise 修改以下,其原理和Array.prototype.reduce+Promise版本相似bash

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

複製代碼

其餘

Array.prototype.forEachArray.prototype.filterArray.prototype.someArray.prototype.every等方法和Array.prototype.map相似,就不過多贅述async

相關文章
相關標籤/搜索