web-dev-qa-db-ja.com

その場合、if-elseを約束どおりに処理する方法は?

場合によっては、promiseオブジェクトから戻り値を取得するときに、次のように、値の条件に応じて2つの異なるthen()プロセスを開始する必要があります。

promise().then(function(value){
    if(//true) {
        // do something
    } else {
        // do something 
    }
})

私はおそらく次のように書くことができると考えています:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        ifTruePromise().then();
    } else {
        ifFalsePromise().then();
    }
})

しかし、これに関して、2つの質問があります。

  1. 新しいpromise-thenプロセスをpromiseで開始することをお勧めするかどうかはわかりません。

  2. 最後の1つの関数を呼び出すために2つのプロセスが必要な場合はどうなりますか?それは、彼らが同じ「端末」を持っていることを意味します

元のチェーンを次のように維持するために、新しい約束を返そうとしました。

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        // and return it
        return ifTruePromise();
    } else {
        // do something, no new promise
        // hope to stop the then chain
    }
}).then(// I can handle the result of ifTruePromise here now);

ただし、この場合、trueまたはfalseに関係なく、次のthenは機能します。

それで、それを処理するためのベストプラクティスは何ですか?

67
Brick Yang

関数がプロミスを返す限り、最初に提案した方法を使用できます。

以下のフィドルは、最初に解決される値が何であるかに応じて、異なるチェーンパスをどのように取ることができるかを示しています。

function myPromiseFunction() {
        //Change the resolved value to take a different path
    return Promise.resolve(true);
}

function conditionalChaining(value) {
    if (value) {
        //do something
        return doSomething().then(doSomethingMore).then(doEvenSomethingMore);
    } else {
        //do something else
        return doSomeOtherThing().then(doSomethingMore).then(doEvenSomethingMore);
    }
}

function doSomething() {
    console.log("Inside doSomething function");
    return Promise.resolve("This message comes from doSomeThing function");
}

function doSomeOtherThing() {
    console.log("Inside doSomeOtherthing function");
    return Promise.resolve("This message comes from doSomeOtherThing function");
}

function doSomethingMore(message) {
    console.log(message);
    return Promise.resolve("Leaving doSomethingMore");
}

function doEvenSomethingMore(message) {
    console.log("Inside doEvenSomethingMore function");
    return Promise.resolve();
}

myPromiseFunction().then(conditionalChaining).then(function () {
    console.log("All done!");
}).
catch (function (e) {

});

また、1つの条件付きチェーンを作成し、リターンプロミスを変数に割り当ててから、いずれかの方法で実行する必要のある関数を実行し続けることもできます。

function conditionalChaining(value){
    if (value) {
        //do something
        return doSomething();
    } else{
        //do something else
        return doSomeOtherThing();
    }
}

var promise = myPromiseFunction().then(conditionalChaining);

promise.then(function(value){
    //keep executing functions that should be called either way
});
46
Daniel B

条件付きプロミスを使用するための簡単なパッケージを作成しました。

確認したい場合:

npmページ: https://www.npmjs.com/package/promise-tree

およびgithub: https://github.com/shizongli94/promise-tree

パッケージが問題をどのように解決するかを尋ねるコメントに応えて:

1、2つのオブジェクトがあります。

2、このパッケージのBranchオブジェクトは、then()またはcatch()で使用するonFulfilledやonRejectedなどの関数の一時的な保管場所です。 Promiseの対応するものと同じ引数を取るthen()やcatch()などのメソッドがあります。 Branch.then()またはBranch.catch()でコールバックを渡すときは、Promise.then()およびPromise.catch()と同じ構文を使用します。その後、コールバックを配列に保存する以外は何もしません。

3、Conditionは、チェックおよび分岐のための条件およびその他の情報を格納するJSONオブジェクトです。

4、promiseコールバックで条件オブジェクトを使用して条件(ブール式)を指定します。条件は、渡された情報を保存します。必要な情報がすべてユーザーから提供された後、条件オブジェクトはメソッドを使用して、以前にBranchオブジェクトに保存された約束チェーンとコールバック情報を取得する完全に新しいPromiseオブジェクトを構築します。ここで少し注意が必要なのは、保存されたコールバックをチェーンする前に、最初に手動で構築したPromiseを(ユーザーではなく実装者として)解決/拒否する必要があることです。そうしないと、新しいプロミスチェーンが開始されないためです。

5、イベントループのおかげで、Stem Promiseオブジェクトを取得する前または後にBranchオブジェクトをインスタンス化でき、相互に干渉しません。ここでは、構造がツリーに似ているため、「ブランチ」および「ステム」という用語を使用します。

サンプルコードは、npmページとgithubページの両方にあります。

ところで、この実装により、ブランチ内にブランチを作成することもできます。また、ブランチは、条件を確認する場所と同じ場所にある必要はありません。

4
szl1919

これは私がfetch()でそれをどのように行ったかです

 fetch().then(res => res.ok ? res : false).then(res => {
    if (res) {
        //res ok
    } else {
       //res not ok
    }

});
0
Servus