Array.forEach结束回调
Array.forEach Callback at the end
我正在使用 javascript 的 Array.forEach
函数为列表的每个元素获取不同的消息。所以我正在使用 forEach
函数,我正在寻找一个 way
来执行我的 callback
函数 cb(result)
当 foreach 完成时都执行 .forEach
和 msgAfterTimeout
。我读到有一个叫做 promises
的东西,但我真的不知道如何在这里使用它们。
function msgAfterTimeout (who, timeout, onDone) {
setTimeout(function () {
onDone(" Hello " + who + "!");
}, timeout);
}
var test="";
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}];
function dispName(cb)
{
list.forEach(function(item, index)
{
msgAfterTimeout(item.name, 200, function (msg)
{
test=msg+"\n";
});
cb(result);
});
}
dispName(function(data){
console.log(data);
});
function msgAfterTimeout (who, timeout, onDone) {
setTimeout(function () {
onDone(" Hello " + who + "!");
}, timeout);
}
var test= "";
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}];
function newFunc(list, i, endCb) {
var name = list[i].name;
msgAfterTimeout(name, 200, function(msg) {
var test = msg + "\n";
console.log(test);
if(i+1 == list.length) {
endCb();
}
else {
newFunc(list, i+1, endCb);
}
});
}
function dispName(cb)
{
newFunc(list, 0 , cb);
}
dispName(function(){
console.log("Done with all!");
});
这输出:
Hello foo!
Hello Jean!
Done with all!
这是你的 Promises 示例:
var list = [{name: "foo", surname: "bar"}, {name: "Jean", surname: "dupond"}];
function msgAfterTimeout(who, timeout) {
return new Promise(resolve =>
setTimeout(
() => resolve(" Hello " + who + "!"),
timeout)
);
}
Promise.all(
list.map(item => msgAfterTimeout(item.name, 200))
).then(
result => console.log(result.join('\n'))
);
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
forEach
处理 系列 中的内容,因此为了这个答案,让我们假设这是一项要求。 Promise.all
正如@georg 所展示的那样,它将处理 并行 中的项目——这是一个很好的答案,但如果系列是你真正需要的,它不会帮助你。
Array.prototype 方法 reduce
、map
和 forEach
是同步的,但您可以轻松创建异步变体。您在这里使用 forEach
但实际上您是在手动执行 reduce
。所以我们将从实现异步 reducek
开始,然后从那里开始
不要太担心了解 reducek
本身。您需要知道的是 reducek
和 reduce
之间的主要区别在于,reducing 函数接收一个额外的回调参数,该参数在每个项目完成时调用,而 reducek
有自己的回调当整个输入列表完成时。
function reducek (f, acc, [x, ...xs], k) {
if (x === undefined)
return k (acc)
else
return f (acc, x, y => reducek (f, y, xs, k))
}
function msgAfterTimeout (who, timeout, onDone) {
return setTimeout(onDone, timeout, "Hello " + who + "!")
}
function messageReducer (acc, item, done) {
return msgAfterTimeout(item.name, 200, function (text) {
return done([...acc, text])
})
}
function displayName (list, done) {
// use our async reduce here
return reducek (messageReducer, [], list, done)
}
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}]
displayName (list, function (texts) {
console.log("Done!", texts.join(' '))
})
// Done! Hello foo! Hello Jean!
注意事项...
不再手动执行 reduce——而不是使用 test
状态初始化为 ''
的变量(空字符串),reducek
接受初始值作为论据。
这里我们使用 []
的初始状态(空数组)来存储每个文本。完成后,我们使用 texts.join(' ')
.
将文本连接在一起
不是另一个仪式...
所有这些都是很多仪式,延续不一定是异步流控制的最佳选择。事实上,JavaScript 引入 Promises 是因为需要更好的工具。
// instead of returning a timeout, return a Promise
function msgAfterTimeout (who, timeout) {
return new Promise(function (resolve) {
setTimeout(resolve, timeout, "Hello " + who + "!")
})
}
// new async/await syntax - work with Promises in a most elegant fashion
// no more callback parameter; async implicitly returns a Promise
<b>async</b> function displayName (list) {
let texts = []
for (let item of list)
texts.push(<b>await</b> msgAfterTimeout(item.name, 200))
return texts
}
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}]
// instead of a callback, chain a .then on the returned Promise
displayName(list).then(texts => console.log("Done!", texts.join(' ')))
// Done! Hello foo! Hello Jean!
注意:如果您需要支持旧版浏览器,async
/await
需要使用 Babel 之类的工具进行转译。
我正在使用 javascript 的 Array.forEach
函数为列表的每个元素获取不同的消息。所以我正在使用 forEach
函数,我正在寻找一个 way
来执行我的 callback
函数 cb(result)
当 foreach 完成时都执行 .forEach
和 msgAfterTimeout
。我读到有一个叫做 promises
的东西,但我真的不知道如何在这里使用它们。
function msgAfterTimeout (who, timeout, onDone) {
setTimeout(function () {
onDone(" Hello " + who + "!");
}, timeout);
}
var test="";
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}];
function dispName(cb)
{
list.forEach(function(item, index)
{
msgAfterTimeout(item.name, 200, function (msg)
{
test=msg+"\n";
});
cb(result);
});
}
dispName(function(data){
console.log(data);
});
function msgAfterTimeout (who, timeout, onDone) {
setTimeout(function () {
onDone(" Hello " + who + "!");
}, timeout);
}
var test= "";
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}];
function newFunc(list, i, endCb) {
var name = list[i].name;
msgAfterTimeout(name, 200, function(msg) {
var test = msg + "\n";
console.log(test);
if(i+1 == list.length) {
endCb();
}
else {
newFunc(list, i+1, endCb);
}
});
}
function dispName(cb)
{
newFunc(list, 0 , cb);
}
dispName(function(){
console.log("Done with all!");
});
这输出:
Hello foo! Hello Jean! Done with all!
这是你的 Promises 示例:
var list = [{name: "foo", surname: "bar"}, {name: "Jean", surname: "dupond"}];
function msgAfterTimeout(who, timeout) {
return new Promise(resolve =>
setTimeout(
() => resolve(" Hello " + who + "!"),
timeout)
);
}
Promise.all(
list.map(item => msgAfterTimeout(item.name, 200))
).then(
result => console.log(result.join('\n'))
);
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
forEach
处理 系列 中的内容,因此为了这个答案,让我们假设这是一项要求。 Promise.all
正如@georg 所展示的那样,它将处理 并行 中的项目——这是一个很好的答案,但如果系列是你真正需要的,它不会帮助你。
Array.prototype 方法 reduce
、map
和 forEach
是同步的,但您可以轻松创建异步变体。您在这里使用 forEach
但实际上您是在手动执行 reduce
。所以我们将从实现异步 reducek
开始,然后从那里开始
不要太担心了解 reducek
本身。您需要知道的是 reducek
和 reduce
之间的主要区别在于,reducing 函数接收一个额外的回调参数,该参数在每个项目完成时调用,而 reducek
有自己的回调当整个输入列表完成时。
function reducek (f, acc, [x, ...xs], k) {
if (x === undefined)
return k (acc)
else
return f (acc, x, y => reducek (f, y, xs, k))
}
function msgAfterTimeout (who, timeout, onDone) {
return setTimeout(onDone, timeout, "Hello " + who + "!")
}
function messageReducer (acc, item, done) {
return msgAfterTimeout(item.name, 200, function (text) {
return done([...acc, text])
})
}
function displayName (list, done) {
// use our async reduce here
return reducek (messageReducer, [], list, done)
}
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}]
displayName (list, function (texts) {
console.log("Done!", texts.join(' '))
})
// Done! Hello foo! Hello Jean!
注意事项...
不再手动执行 reduce——而不是使用
test
状态初始化为''
的变量(空字符串),reducek
接受初始值作为论据。这里我们使用
[]
的初始状态(空数组)来存储每个文本。完成后,我们使用texts.join(' ')
. 将文本连接在一起
不是另一个仪式...
所有这些都是很多仪式,延续不一定是异步流控制的最佳选择。事实上,JavaScript 引入 Promises 是因为需要更好的工具。
// instead of returning a timeout, return a Promise
function msgAfterTimeout (who, timeout) {
return new Promise(function (resolve) {
setTimeout(resolve, timeout, "Hello " + who + "!")
})
}
// new async/await syntax - work with Promises in a most elegant fashion
// no more callback parameter; async implicitly returns a Promise
<b>async</b> function displayName (list) {
let texts = []
for (let item of list)
texts.push(<b>await</b> msgAfterTimeout(item.name, 200))
return texts
}
var list = [{name:"foo",surname:"bar"},{name:"Jean",surname:"dupond"}]
// instead of a callback, chain a .then on the returned Promise
displayName(list).then(texts => console.log("Done!", texts.join(' ')))
// Done! Hello foo! Hello Jean!
注意:如果您需要支持旧版浏览器,async
/await
需要使用 Babel 之类的工具进行转译。