最近有個業務場景,須要在循環中執行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.forEach
、Array.prototype.filter
、Array.prototype.some
、Array.prototype.every
等方法和Array.prototype.map
相似,就不過多贅述async