承诺的复杂排序 - 嵌套

时间:2016-01-23 06:30:59

标签: node.js promise

经过大量谷歌搜索后,我无法确认解决此问题的正确方法。下面的代码按预期运行,但我有一种严肃的感觉,我没有以正确的方式接近这个,我正在为自己找到问题。

以下代码由主app.js文件启动,并传递一个位置以开始从mongoDB加载XML文件并将其处理为mongoDB



exports.processProfiles = function(path) {

  var deferrer  = q.defer();
  
  q(dataService.deleteProfiles())  // simple mongodb call to empty the Profiles collection
    .then(function(deleteResult) {
      return loadFilenames(path); // method to load all filenames in the given path using fs
    })
    .then(function(filenames) {
      // now we have all the file names lets load and save
      filenames.forEach(function(filename) {
                  
        // Here is where i think the problem is!
        // kick off another promise chain for the dynamically sized array of files to process
        q(loadFileContent(path, filename)) // first we load the data in the file
          .then(function(inboundFile) {
            // then parse XML structure to my new shiny JSON structure
            // and ask Mongo to store it for me
              return dataService.createProfile(processProfileXML(filename, inboundFile));
          })
          .done(function(result) {
            console.log(result);
          })
        });
      })
      .catch(function(err) {
        deferrer.reject('Unable to Process Profile records : ' + err);
      })
      .done(function() {
        deferrer.resolve('Profile Processing Completed');
      });

   return deferrer.promise;
}




虽然这段代码有效,但这些是我主要关心的问题,但经过几个小时的Google阅读后无法自行解决。

1)这是阻止吗?如果这是我想要的异步运行,很难理解到控制台的读出 - 我认为这是建议我是否做了一些根本错误的事情会很棒

2)嵌套的承诺是一个坏主意,我应该将它链接到外部承诺 - 我已经尝试但无法获得任何编译或运行。

1 个答案:

答案 0 :(得分:2)

我在很长一段时间内都没有使用过Q,但我认为你需要做的就是让它知道你即将交出一系列承诺,这些承诺需要在继续之前得到满足。

此外,当您在一段代码中等待多个承诺时,而不是进一步嵌套,一旦满意,就将备份的'set'备份。

q(dataService.deleteProfiles())  // simple mongodb call to empty the Profiles collection
.then(function (deleteResult) {
    return loadFilenames(path); // method to load all filenames in the given path using fs
})
.then(function (filenames) {
    return q.all(
        filenames.map(function (filename) {
            return q(loadFileContent(path, filename)) { /* Do stuff with your filenames */ });
        })
    );
.then(function (resultsOfLoadFileContentsPromises) {
    console.log('I did stuff with all the things');
)
.catch(function(err) {});

你所拥有的不是“阻挡”。但是你真正对承诺所做的就是把事情变成一个新的“阻塞”部分。您拥有的块越多,您的代码将显示的异步越多。如果除了这个承诺之外什么都没有,它仍然会出现程序性的。

但是,在父母承诺之后解决之前,内心承诺仍必须解决。

你所拥有的内心承诺本身并不是坏事,我个人会将它们分解成单独的文件以便更容易推理,但我不会将其定义为“坏”,除非不需要那种内在承诺存在,但是在可能的情况下(在你的例子中)我已经进行了调整,所以我重新启动了新的部分的下一组承诺,以便在数据得到它之后处理数据。

(我对Q不太好,这段代码可能需要进一步调整)。