在我的Web应用程序中:
如果使用javascript中的map方法在通过数组的循环执行过程中将元素推到数组上会发生什么?
或者换句话说,我可以假设使用map方法遍历数组时,map方法遍历数组快照吗?
我想避免使用df['a'] == 'foo' and pd.Series(df.index.isin(['2019-01-05','2019-01-09']))
来确保我遍历快照。
任何人都可以提供可以测试此方案的代码吗?
答案 0 :(得分:1)
您实际上不需要测试; The ECMAScript spec很清楚:
在第一次调用callbackfn之前设置map处理的元素的范围。调用map开始后追加到数组的元素将不会被callbackfn访问。如果更改了数组的现有元素,则传递给callbackfn的值将是映射访问它们时的值;在地图调用开始后被访问之前被删除的元素不会被访问。
如果要测试,可以使用类似以下的内容:
const arr = [5];
const result = arr.map( x => {
console.log( `Visiting ${x}` );
arr.push( x + 1 );
return 2*x;
} );
console.log( arr ); // Has two elements
console.log( result ); // Only has one element
但是,当您说:
或者换句话说,我可以假设使用map方法遍历数组时,map方法遍历数组快照吗?
与您以前的措辞不同。映射回调不会访问被压入数组的元素,但是已替换的元素将成为其新值。您可以像这样测试:
const arr = [0,0];
const result = arr.map( x => {
console.log( `Visiting ${x}` );
arr[1] = 3;
return 2*x;
} );
console.log( result );
注意:Array#map是同步的,并且JavaScript是单线程的,因此,如果回调中的代码没有使数组发生变化,则在迭代过程中就不可能使数组发生变化(其他代码,即IE firebase,无法在地图运行时运行。
const arr = [0,1,2,3,4,5];
// Change a random value in arr every 4 milliseconds
// Emulates Firebase modifying the array
setInterval( function ( ) {
arr[~~(Math.random()*6)] = Math.random( );
}, 4 );
// (async), Logs values after they've been modified
setTimeout( function ( ) {
console.log( 'Logging array values after one second' );
arr.map( x => console.log( x ) );
}, 1000 );
// Logs the values unmodified, async code, such as Firebase can't affect this
console.log( '(sync) with a 100ms spinlock between each map callback, to demonstrate that the array cannot be modified externally during the map.' );
arr.map( x => {
console.log( x );
const start = +new Date;
while( +new Date < start + 100 ); // Wait for 100 milliseconds
} );