我正在使用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);
});
答案 0 :(得分:0)
<form method="POST" action="{{ action('ProductController@addToCart') }}/add">
输出:
你好foo! 你好让! 完成所有工作!
答案 1 :(得分:0)
以下是Promises的示例:
val usersTable = sqlContext.sql("select a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, an, ao, ap, aq, ar, as, at from abcdef").rdd
usersTable: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[39] at rdd at <console>:67
val finalUsers = usersTable.flatMap(e => (e(0).toString, e(1).toString, e(2).toString, e(3).toString, e(4).toString, e(5).toString, e(6).toString, e(7).toString, e(8).toString, e(9).toString, e(10).toString, e(11).toString, e(12).toString, e(13).toString, e(14).toString, e(15).toString, e(16).toString, e(17).toString, e(18).toString, e(19).toString, e(20).toString, e(21).toString, e(22).toString, e(23).toString, e(24).toString, e(25).toString, e(26).toString, e(27).toString, e(28).toString, e(29).toString, e(30).toString, e(31).toString, e(32).toString, e(33).toString, e(34).toString, e(35).toString, e(36).toString, e(37).toString, e(38).toString, e(39).toString, e(40).toString, e(41).toString, e(42).toString, e(43).toString, e(44).toString, e(45).toString))
error: object Tuple46 is not a member of package scala
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
答案 2 :(得分:0)
forEach
处理系列中的内容,因此为了这个答案,我们假设这是一个要求。 @georg演示的Promise.all
将处理 parallel 中的项目 - 这是一个很好的答案,但如果系列是您真正需要的,它将无法帮助您。< / p>
Array.prototype方法reduce
,map
和forEach
是同步的,但您可以轻松制作异步变体。您在此处使用forEach
,但实际上是在手动执行reduce
。因此,我们首先实现异步reducek
,然后从那里开始
不要过分担心理解reducek
本身。您需要知道的是reducek
和reduce
之间的主要区别在于reduce函数接收到在每个项完成时调用的额外回调参数,并且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!
&#13;
需要注意的重要事项......
不再手动执行reduce - 而不是使用以test
状态初始化的''
变量(空字符串),reducek
接受初始值作为参数。
在这里,我们使用[]
(空数组)的初始状态来存储每个文本。完成后,我们会使用texts.join(' ')
一起加入文本。
不是另一场仪式......
所有这些都是很多仪式,并且延续不一定是异步流量控制的最佳选择。事实上,Promises被带到了JavaScript,因为需要一个更好的工具。
// 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
async function displayName (list) {
let texts = []
for (let item of list)
texts.push(await 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!
注意:如果您需要支持较旧的浏览器,则需要使用像Babel这样的内容来转换async
/ await
。