2017-06-23 12 views
0

各サブプロジェクトを横断してラリーから詳細を取得しようとしています。NodeJS再帰約束ラリー

しかし、最後にconsole.log(出力)がありますが、何も印刷されません。配列にプッシュした直後に出力を出力すると、その値を見ることができます。私はここで間違って何をしていますか?

function getProjects(projectRef, output) { 
    var deferred = Promise.defer(); 
    callAc(projectRef, ['FormattedID', 'Name', 'Children', 'Parent', 'TeamMembers'], function(result) { 
     result.Object.Results.forEach(function(item) { 
      output.push(item.Name); 
      getProjects(item.Children._ref.split('webservice/v2.0')[1], output) 
       .then(function() { 
        deferred.resolve(); 
       }); 
     }); 
    }); 
    return deferred.promise; 
} 

function callAc(ref, parameters, callback) { 
    restApi.get({ 
     ref: ref, 
     fetch: parameters, 
     scope: { 
      workspace: '/workspace/XXXX' 
     }, 
     requestOptions: {} 
    }).then(function(result) { 
     callback(result); 
    }).fail(function(errors) { 
     console.log(errors); 
    }); 
} 

var output = []; 
var projectRef = '/Project/<some_project_id>/Children'; 
getProjects(projectRef, output) 
    .then(function() { 
     console.log('fetched all projects'); 
     console.log(output); 
    }); 

出典:https://mostafa-samir.github.io/async-recursive-patterns-pt2/

+0

です。その場合、 'getProjects'の最後の呼び出しで作成された約束は決して解決されないので、' getProjects'の最初の呼び出しで作成された全体的な約束は決して解決されないので、 'then'コールバックは決して呼び出されません。 –

答えて

0

まず、あなたは間違っているのチュートリアルを見ています。現在、標準Promiseにはfail()またはdefer()がありません。失敗ハンドラは、then()の2番目のパラメータにあります。

もう1つの問題はコールバックです。 Promiseの目的の1つは、コールバックを減らすことです。私はthen()にコールバックを再配置しました。

最後に、元のコードに無限ループがあり、再帰終了1 == 0を追加しました。この例では

var restApiget = function(ref) { 
    console.log('restApiget', ref); 
    var child = childGen.next().value; 
    return Promise.resolve(child); 
} 

var childMaker = function*() { 
    yield ['1', '2']; 
    yield ['4', '5']; 
    yield ['6', '7']; 
    yield ['8', '9']; 
    while (true) 
     yield []; 
} 
childGen = childMaker(); 

function getProjects(projectRef, output) { 
    return callAc(projectRef, ['FormattedID', 'Name', 'Children', 'Parent', 'TeamMembers']) 
     .then(function(res) { 
      output.push(projectRef); 
      console.log('callAc', 'then', res); 
      var promises = []; 
      res.forEach((i) => { 
       promises.push(getProjects(i, output)); 
      }); 
      if (promises.length > 0) { 
       return Promise.all(promises); 
      } 
      return Promise.resolve(res); 
     }); 
} 

function callAc(ref, parameters, callback) { 
    return restApiget(ref); 
} 

var output = []; 
var projectRef = 'root'; 

getProjects(projectRef, output) 
    .then(function(res) { 
     console.log('fetched all projects'); 
     console.log('mess up', res); 
     console.log(output); 
    }) 
    .catch(function(err) { 
     console.log('catch', err); 
    }) 

私はあなた `restApi`呼び出しが失敗したときにcallback`が呼び出されません`、正しくあなたのコードを読んでいる場合は、「プロジェクト」の構造は、

 root 
    / \ 
    1  2 
    /\ /\ 
    4 5 6 7 
/\  
8 9 
+0

私はforEachを自分のコードに持っていますが、そのことについてどのように提案するのですか? – karthikeayan

+0

それは無限ループではありません。なぜなら、すべての反復で子供の参照を渡しているからです。ある時点で子供はいないでしょう。 – karthikeayan

+0

申し訳ありません。初めてforEachループを捕まえていない、無限ループだと思いました。私は答えを更新しました。私は 'forEach'を処理するために' Promise.all'を使います。しかし、欠点は、 'res'を台無しにすることです。結果をキャプチャするために 'output'を使用して受け入れることができれば、それはうまくいくはずです。 – benjah1