我有一个JSON对象,我需要清理以$开头的属性。因此,下面的给定结构应摆脱$aaa$bbb$ccc$eee

{
  $aaa: "$aaa",
  bbb: "bbb",
  $ccc: {
    $ccc2: "$ccc2",
    ccc2a: "ccc2a"
  },
  ddd: {
    $ddd: "$ddd2",
    ddd2a: "ddd2a"
  },
  $eee: "$eee",
  fff: "fff"
}


我还想使其异步运行并使用Promises。但是,我遇到了麻烦。它无法清除$eee,并且不确定我哪里出错了。以下是完整的代码和plunker is here

function clean$(obj1) {
  var obj = obj1;
  return new Promise(function(res, rej) {
    setTimeout(function() {
      for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
          if (i.match(/^\$/)) {
            console.log("delete this " + i);
            delete obj[i];
          } else if (typeof obj[i] === "object") return clean$(obj[i]);
        }
      }
      res();
    }, 1000);
  })
}

sample = {
  $aaa: "$aaa",
  bbb: "bbb",
  $ccc: {
    $ccc2: "$ccc2",
    ccc2a: "ccc2a"
  },
  ddd: {
    $ddd: "$ddd2",
    ddd2a: "ddd2a"
  },
  $eee: "$eee",
  fff: "fff"
}

clean$(sample).then(function(res) {
  console.log("why it never gets here???");
})

最佳答案

正如@knolleary已经说过的那样,当您调用$clean时,您的内部超时函数将返回,而不是继续。

在这一点上,您的外部关闭已经返回了一个承诺。这个承诺只是在等待调用res的东西,但是这种调用永远不会发生。

最初的呼叫正在等待这个诺言解决,因此它可以写日志消息“为什么它永远不会到达这里???”。

您必须确保在所有情况下都调用resolve方法。另外,必须等待内部调用$clean解析。

这是一个可行的解决方案:

function clean$(obj1) {
  var obj = obj1;
  return new Promise(function(res, rej) {
    setTimeout(function() {
      var promisesToWaitFor = [];
      for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
          if (i.match(/^\$/)) {
            console.log("delete this " + i);
            delete obj[i];
          } else if (typeof obj[i] === "object") {
            promisesToWaitFor.push(clean$(obj[i]));
          }
        }
      };
      Promise.all(promisesToWaitFor).then(res);
    }, 1000);
  })
}


Plunkr Fork...

关于javascript - 为什么我的Promises递归Javascript函数失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30631939/

10-09 19:29