2017-12-13 16 views
1

私はpromiseにラップされたコードをいくつか持っています。このコードは、リモートDB内のいくつかのレコードを編集し、編集されたレコードの数を返します。編集したレコードの数が0より大きい場合(つまり、いくつかの作業が完了している場合)、同じメソッドを何度も繰り返し実行してから、0が返されます。前回実行した結果に応じて同じ約束をもう一度実行するにはどうすればよいですか?

私はいくつかの方法を試しましたが、それらはすべて終了しません(つまり、解決が呼び出されない)か、正常に実行されません。

最初のバージョンは、私が試した:

const doEdits =() => { 
    return new Promise((resolve, reject) => { 
    someDB.performEdits() 
    .then(count => { 
     if (count > 0) { 
     doEdits() 
     } else { 
     resolve() 
     } 
    }) 
    .catch(reject) 
    }) 
} 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(doEdits) 
    .catch(reject) 
}) 

セカンドバージョンは、私が試した:

const doEdits =() => { 
    return new Promise((resolve, reject) => { 
    someDB.performEdits() 
    .then(count => { 
     resolve(count) 
    }) 
    .catch(reject) 
    }) 
} 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(doEdits) 
    .then(count => { 
    if (count > 0) { 
     return doEdits() // 'doEdits()' did not work... 
    } else { 
     resolve() 
    } 
    }) 
    .catch(reject) 
}) 

任意およびすべての提案は歓迎されています。

+0

あなたは 'doEdits'の後で解決していません。約束はいつも最終的に解決されるか、または拒否される必要があります。 – Eric

+0

@ErikKralj、もし最初の例を 'if(count> 0)'の後に書いているなら、 '.then(...)'の後に返された結果をチェックする必要があります。何度もやり直してください... –

答えて

3

はい、ifブランチでresolveと決して電話していませんでした。しかし、ここではresolve関数を使用しないでください。Promise constructor antipatternを避けてください!ただ、

function doEdits() { 
    return someDB.performEdits().then(count => { 
    if (count > 0) { 
     return doEdits(); 
    } else { 
     return undefined; // ??? 
    } 
    }); 
} 

return someDB.init().then(doEdits); 
+0

これはうまくいきます! - ありがとう –

1

はスパゲッティ

をしないでくださいあなたは本当にあなたが使用している基本的なライブラリがすでにあなたにpromise.Thisアプローチを返している、特に以来、約束の束を作成する必要はありませんありません。最初の約束の後のデシベルの呼び出しから

const doEdits = count => { 
    if(count > 0) { 
    return someDB.performEdits().then(doEdits); 
    } 
}; 

return someDB.init() 
    .then(() => { 
    performEdits().then(doEdits) 
    }); 

この意志チェーンの約束:すべての余分な醤油なしであなたの目標を達成する必要があります。それ以降のすべてのメッセージは、返された約束(つまり、解決または拒否を待つ)に対して作用し、渡される前に解決されると新しい約定に置き換えられる可能性があります(および)。


あなたのコードが

あなたが約束をインスタンス化しようとしているかを決定したら、あなたは決意を扱うの責任を取り、コールバックを拒否している動作しませんでしたなぜ - とあなたの自己をコミットしますコールバック地獄に。約束事が解決しようとしているものとまったく同じです。両方のスニペットで

は、できるだけ早くあなたが count > 0を参照して doEditsを呼び出すよう、あなたは、以前の約束を放棄し、新しいものをインスタンス化し、あなたのきっかけに国連 resolve Dの約束の道で終わります。解決策と拒否の機能を新しい約束に引き渡し、新しい約束が解決または拒否されたときに解決または拒否されることを確認する必要があります。それは無駄だし、また33人の不合格反復performEdits場合はケースを処理しないので

はこの

function doEdits(previousPromise) { 
    someDB.performEdits() 
    .then((count) => { 
    if(count > 0) { 
     doEdits(this); 
    } else { 
     resolve(); 
    } 
    }) 
}; 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(() => { 
    someDB.performEdits() 
    .then((count) => { 
     if(count > 0) { 
     doEdits(this); 
     } else { 
     resolve(); 
     } 
    }) 
    }) 
}); 

をしないでください。理論的には、これはうまくいくかもしれませんが、推論するのがずっと難しくなります。