我有一个关于原生数组的问题。JavaScript的每一个实现都是异步的吗? 例如,如果我调用:
[many many elements].forEach(function () {lots of work to do})
这将是非阻塞的吗?
我有一个关于原生数组的问题。JavaScript的每一个实现都是异步的吗? 例如,如果我调用:
[many many elements].forEach(function () {lots of work to do})
这将是非阻塞的吗?
当前回答
编辑2018-10-11: 看起来下面描述的标准很有可能无法通过,可以考虑管道作为替代方案(虽然行为不完全相同,但方法可以在类似的庄园中实现)。
这就是为什么我对es7感到兴奋,在未来你将能够做一些像下面的代码(一些规格不完整,所以使用时要小心,我会尽量保持最新)。但是基本上使用新的::bind操作符,你将能够在对象上运行一个方法,就好像对象的原型包含了这个方法一样。例如[Object]::[Method],通常你会调用[Object].[ObjectsMethod]
注意今天(7月24日-16日)要做到这一点,并让它在所有浏览器中都能工作,你需要编译以下功能的代码:导入/导出,箭头函数,承诺,Async / Await,以及最重要的函数绑定。如果必要,下面的代码可以修改为只使用函数绑定,所有这些功能今天都可以使用babel。
YourCode.js(其中“许多工作要做”必须简单地返回一个承诺,在异步工作完成时解决它。)
import { asyncForEach } from './ArrayExtensions.js';
await [many many elements]::asyncForEach(() => lots of work to do);
ArrayExtensions.js
export function asyncForEach(callback)
{
return Promise.resolve(this).then(async (ar) =>
{
for(let i=0;i<ar.length;i++)
{
await callback.call(ar, ar[i], i, ar);
}
});
};
export function asyncMap(callback)
{
return Promise.resolve(this).then(async (ar) =>
{
const out = [];
for(let i=0;i<ar.length;i++)
{
out[i] = await callback.call(ar, ar[i], i, ar);
}
return out;
});
};
其他回答
编辑2018-10-11: 看起来下面描述的标准很有可能无法通过,可以考虑管道作为替代方案(虽然行为不完全相同,但方法可以在类似的庄园中实现)。
这就是为什么我对es7感到兴奋,在未来你将能够做一些像下面的代码(一些规格不完整,所以使用时要小心,我会尽量保持最新)。但是基本上使用新的::bind操作符,你将能够在对象上运行一个方法,就好像对象的原型包含了这个方法一样。例如[Object]::[Method],通常你会调用[Object].[ObjectsMethod]
注意今天(7月24日-16日)要做到这一点,并让它在所有浏览器中都能工作,你需要编译以下功能的代码:导入/导出,箭头函数,承诺,Async / Await,以及最重要的函数绑定。如果必要,下面的代码可以修改为只使用函数绑定,所有这些功能今天都可以使用babel。
YourCode.js(其中“许多工作要做”必须简单地返回一个承诺,在异步工作完成时解决它。)
import { asyncForEach } from './ArrayExtensions.js';
await [many many elements]::asyncForEach(() => lots of work to do);
ArrayExtensions.js
export function asyncForEach(callback)
{
return Promise.resolve(this).then(async (ar) =>
{
for(let i=0;i<ar.length;i++)
{
await callback.call(ar, ar[i], i, ar);
}
});
};
export function asyncMap(callback)
{
return Promise.resolve(this).then(async (ar) =>
{
const out = [];
for(let i=0;i<ar.length;i++)
{
out[i] = await callback.call(ar, ar[i], i, ar);
}
return out;
});
};
这些代码片段将使您更好地理解forEach和forOf的比较。
/* eslint-disable no-console */ async function forEachTest() { console.log('########### Testing forEach ################ ') console.log('start of forEachTest func') let a = [1, 2, 3] await a.forEach(async (v) => { console.log('start of forEach: ', v) await new Promise(resolve => setTimeout(resolve, v * 1000)) console.log('end of forEach: ', v) }) console.log('end of forEachTest func') } forEachTest() async function forOfTest() { await new Promise(resolve => setTimeout(resolve, 10000)) //just see console in proper way console.log('\n\n########### Testing forOf ################ ') console.log('start of forOfTest func') let a = [1, 2, 3] for (const v of a) { console.log('start of forOf: ', v) await new Promise(resolve => setTimeout(resolve, v * 1000)) console.log('end of forOf: ', v) } console.log('end of forOfTest func') } forOfTest()
这是一个不需要第三方库就可以使用的简短异步函数
Array.prototype.each = function (iterator, callback) {
var iterate = function () {
pointer++;
if (pointer >= this.length) {
callback();
return;
}
iterator.call(iterator, this[pointer], iterate, pointer);
}.bind(this),
pointer = -1;
iterate(this);
};
在npm中有一个包,可以为每个循环提供简单的异步。
var forEachAsync = require('futures').forEachAsync;
// waits for one request to finish before beginning the next
forEachAsync(['dogs', 'cats', 'octocats'], function (next, element, index, array) {
getPics(element, next);
// then after all of the elements have been handled
// the final callback fires to let you know it's all done
}).then(function () {
console.log('All requests have finished');
});
这也是allasync的另一个变体
下面是一个小例子,你可以运行来测试它:
[1,2,3,4,5,6,7,8,9].forEach(function(n){
var sum = 0;
console.log('Start for:' + n);
for (var i = 0; i < ( 10 - n) * 100000000; i++)
sum++;
console.log('Ended for:' + n, sum);
});
它将生成如下内容(如果花费的时间太少/太多,可以增加/减少迭代次数):
(index):48 Start for:1
(index):52 Ended for:1 900000000
(index):48 Start for:2
(index):52 Ended for:2 800000000
(index):48 Start for:3
(index):52 Ended for:3 700000000
(index):48 Start for:4
(index):52 Ended for:4 600000000
(index):48 Start for:5
(index):52 Ended for:5 500000000
(index):48 Start for:6
(index):52 Ended for:6 400000000
(index):48 Start for:7
(index):52 Ended for:7 300000000
(index):48 Start for:8
(index):52 Ended for:8 200000000
(index):48 Start for:9
(index):52 Ended for:9 100000000
(index):45 [Violation] 'load' handler took 7285ms