【问题标题】:Array.every() - Return in callback possible?Array.every() - 在回调中返回可能吗?
【发布时间】:2016-03-18 06:14:26
【问题描述】:

我正在解析一个输入文件并使用 Array.every 函数遍历每个元素。根据结构,需要用户手动输入。 因此,例如,如果您有这样的事情:

configData.users.every(function(user){
 if(user.enabled == 1){
    if(user.mobile == 1){
        prompt.start();
        prompt.get(['mCode'], function (err, result) {
         //Do something...
         //return needed here!
        });
    }else{
        //Do something else...
        return true;
    }
 }
});

所以在我的情况下,提示是在用户输入输入时调用回调函数。此时,哪里很清楚,可以处理下一个元素。那么此时如何调用 return 来继续执行 every() 函数呢?

感谢您的帮助。

【问题讨论】:

  • 你说的意思能再清楚一点那么我现在如何调用return来继续every()函数?
  • 好吧,当你为实际元素返回 true 时,every 函数只处理下一个元素。所以我想在代码示例中描述的方法的回调函数中调用它。但它不起作用。也许它是一个范围的事情?
  • 是的,这是一个范围的事情,你不能从回调中返回,它发生在不同的上下文中。您应该使用 Promise 来处理您的问题,这是在执行其他任何操作之前等待回调中发生某些事情的唯一方法。您还需要使用 reduce 而不是 every - 发现这个答案会有所帮助:stackoverflow.com/questions/17757654/…
  • @oshnaps 您关于承诺的陈述不正确。以及整个“这是一个范围的事情,你不能从回调中返回”这句话是错误的。
  • @oshnaps 我不明白 reduce 对我有什么帮助?我正在解析 json 结构。所以不需要对数组的条目求和。 Promise 听起来不错,但我认为您不能将它们与每个功能一起使用。

标签: javascript arrays node.js


【解决方案1】:

你不能同步执行异步的事情,这本质上是你想要做的。正如 cmets 中提到的,promise 是最好的方法。如果要直接写,最简单的做法是:

function handle_users(users) {
  var i = 0;
  function _internal() {
    if (i >= users.length) return;
    var user = users[i];
    if (user.enabled == 1) {
      if (user.mobile == 1) {
        prompt.start();
        prompt.get(['mCode'], function (err, result) {
          //Do something...
          //return needed here!
          i++;
          _internal();
        });
      } else {
        i++; 
        _internal();
        return true;
      }
   }
   internal();
}

我们定义了一个内部函数,我们在prompt.get 的回调中以某种递归方式调用它。

如果你想获取所有用户已经限定或输入了正确的关键字或其他任何信息的信息,那么在顶层保留一个布尔变量,当失败时将其设置为false,然后从函数返回的地方。或者,如果您想在第一次失败时停止处理,就像 every 所做的那样,您可以在 _internal 的顶部检查并立即返回。

【讨论】:

    【解决方案2】:

    好吧,我很确定我的答案 - 如果指向另一个问题的链接没有帮助 - 我会根据您的具体问题进行调整(我使用“何时”,您可以使用您喜欢的 Promise 包) :

    configData.users.reduce(function(lastValue, user){
        return lastValue.then(function(u) {
            if (user.enabled == 1) {
                if (user.mobile == 1) {
                    prompt.start();
                    return when.promise(function(resolve, reject) {
                        prompt.get(['mCode'], function (err, result) {
                            //Do something...
                            //return needed here!
                            resolve(u);
                        });
                    });
                } else {
                    //Do something else...
                    return when.resolve(u);
                }
            }
        });
    }, when.resolve(configData.users[0]));
    

    reduce 不仅仅是对条目求和,关于它的事情是你可以使用你在函数中得到的最后一个值(在某种程度上属于最后一个数组条目)作为下一个值。 我声称这就是您所需要的,因为您想返回一个承诺(以便等待回调中发生的事情)。

    我对其进行了测试,并且它可以正常工作,因为我知道您需要它才能工作,希望我没有错过您在问题中的意图。 现在代码会遍历第一个用户两次,您应该对数组或其他东西进行切片以使其完全按照您的意愿工作。

    请注意,现在您在 user.enabled == 0 上没有返回任何内容,您可能需要添加另一个 else 以根据需要继续减少流程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 2012-01-13
      相关资源
      最近更新 更多