最后的Array.forEach回调

时间:2016-11-23 08:48:58

标签: javascript asynchronous callback es6-promise

我正在使用javascript的Array.forEach函数为列表的每个元素获取不同的消息。所以我正在使用forEach函数,我正在寻找一个way来执行我的callback函数cb(result),当foreach完成后执行.forEachmsgAfterTimeout。我读到有些东西叫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);
});

3 个答案:

答案 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方法reducemapforEach是同步的,但您可以轻松制作异步变体。您在此处使用forEach,但实际上是在手动执行reduce。因此,我们首先实现异步reducek,然后从那里开始

不要过分担心理解reducek本身。您需要知道的是reducekreduce之间的主要区别在于reduce函数接收到在每个项完成时调用的额外回调参数,并且reducek有自己的回调当整个输入列表完成时。

&#13;
&#13;
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;
&#13;
&#13;

需要注意的重要事项......

  1. 不再手动执行reduce - 而不是使用以test状态初始化的''变量(空字符串),reducek接受初始值作为参数。

  2. 在这里,我们使用[](空数组)的初始状态来存储每个文本。完成后,我们会使用texts.join(' ')一起加入文本。

  3. 不是另一场仪式......

    所有这些都是很多仪式,并且延续不一定是异步流量控制的最佳选择。事实上,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