今天看啥  ›  专栏  ›  古桐

如何在循环中串行执行promise

古桐  · 掘金  ·  · 2019-10-15 13:59
阅读 32

如何在循环中串行执行promise

最近有个业务场景,需要在循环中执行promise,并且上一个请求的结果为下一个请求的参数

一个基本的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( () => {
    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,否则就会变成如下结果


# 执行结果
{}
{ 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版本类似


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类似,就不过多赘述




原文地址:访问原文地址
快照地址: 访问文章快照