2017-09-18 8 views
0

約束が新しくなるので、冗長でも構いません。開始時の余分な約束と終了時の余分な約束

私は何かをする約束を返す関数 "extra_promises_at_start_and_end"を書いています。

この関数は、失敗する(つまり、拒否された約束を返す)ことをすぐに知っているかもしれません。質問1:Promise.give_me_a_rejected_promise(..)のようなものがありますか、私のコードのように約束をして拒否しなければなりませんか?

同様に、私の関数 "extra_promises_at_start_and_end"は、約束を返す他の関数を呼び出します。この非同期チェーニングの最後に、私はいくつかの最終処理が必要です。質問2a/2b:私の関数は約束を返すので、この最後の仕事をするという約束をする必要があります。これは正しいですか?私は約束を作成し、すぐにそれを受け入れるか拒否する必要がありますか? Promise.give_me_a_rejected_promise(..)がありますか?

私のコードは期待どおりに機能し、何かが欠けているように感じ、冗長コードを生成します。問題の

コード:

// this is the function that may have redundant code 
// see question 1 and 2 
function extra_promises_at_start_and_end() { 
    // fake out some module scope variable that indicates if this call is allowed to proceed or not 
    let ok_to_proceed = Math.random() > 0.5 

    // this function "extra_promises_at_start_and_end returns" a promise, 
    // Question 1: I need to create a Promise just to reject it immediatly? 
    if (!ok_to_proceed) { 
     return new Promise((resolve, reject) => { reject("failed before starting anything") }) // feels wrong 
    } 

    // do 5 things in sequence 
    return another_module_promise_to_do_something(1).then(() => { 
     return another_module_promise_to_do_something(2) 
    }).then(() => { 
     return another_module_promise_to_do_something(3) 
    }).then(() => { 
     return another_module_promise_to_do_something(4) 
    }).then(() => { 
     return another_module_promise_to_do_something(5) 
    }).then(() => { 
     // need to do something after the above 5 tasks are done, 

     console.log("doing something after all 5 things are done") 

     // this function "extra_promises_at_start_and_end" returns a promise, 
     // Question 2a: I need to create a promise just to resolve it immediatly? 
     return new Promise((resolve, reject) => { resolve(); }) // feels wrong 
     }).catch((id) => { 
      // this function extra_promises_at_start_and_end returns a promise, 
      // Question 2b: I need to create one just to reject it immediatly? 
      return new Promise((resolve, reject) => { reject(id); }) // feels wrong 
     }) 
} 

は、このコードの呼び出し側は約束を期待しています。最後に

// run the test 
console.log("calling something that will return a promise to let me know when it's done"); 
extra_promises_at_start_and_end() 
    .then(() => { 
     console.log("done :)") 
    }).catch((id) => { console.log("failed id = " + id) }) 

、これは行われることになっている方法であれば、私に知らせて、私は約束を使用するための正しい方法を探して停止します

// pretend this is a complex task (ie: not suitable for inlining) 
// done by some other module 
// it returns a promise 
function another_module_promise_to_do_something(id) { 
    console.log("starting " + id) 

    let P = new Promise((resolve, reject) => { 
     console.log(" inside promise " + id) 

     setTimeout(() => { 
      if (Math.random() > 0.1) { 
       console.log(" finished " + id); 
       resolve(); 
      } else { 
       console.log(" failed " + id) 
       reject(id); 
      } 
     }, Math.random() * 1000) 
    }) 

    return P; 
} 

私の機能をテストするためのスタブ。

+1

これは、あなたが、質問1のために探しているものはおそらくです:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject –

答えて

-1

then()およびcatch()の機能は、Promiseの戻り値Promiseです。

コードの最後の大きなチャンクは実際には冗長です。 5番目の連鎖呼び出しの後に処理を行う必要がある場合は、then()then()にするだけです。

は、ここで説明するようにコードの多くの最低限のバージョンです:

const countFromOneToFive =() => { 
 
    if (Math.random() > 0.5) { 
 
    return Promise.reject("Cosmic radiation ruined your promises. Great."); 
 
    } 
 

 
    return Promise.resolve([]) 
 
    .then((countToFive) => { 
 
     countToFive.push(1); 
 
     return countToFive; 
 
    }) 
 
    .then((countToFive) => { 
 
     countToFive.push(2); 
 
     return countToFive; 
 
    }) 
 
    .then((countToFive) => { 
 
     countToFive.push(3); 
 
     return countToFive; 
 
    }) 
 
    .then((countToFive) => { 
 
     countToFive.push(4); 
 
     return countToFive; 
 
    }) 
 
    .then((countToFive) => { 
 
     countToFive.push(5); 
 
     return countToFive; 
 
    }); 
 
}; 
 

 
countFromOneToFive() 
 
    .then((countToFive) => { 
 
    countToFive.forEach((number) => console.log(number)); 
 
    }) 
 
    .catch((error) => { 
 
    console.log(error, "Curses!"); 
 
    });

あなただけの拒否Promiseを返すためにPromise.reject()を使用することができます。これは一番下のcatchステートメントで処理されます。

すべての処理は、できるだけ多くのthen()呼び出しで実行できます。最終的なthen()の後に返信すると、Promiseになります。そこから、約束どおりに扱い、then()catch()を付け加えてください。

-1

1:Promise.give_me_a_rejected_promise(..)のようなものがありますか、または私のコードのように約束をして拒否する必要がありますか?

Promise.reject(err)のように?

//質問2a:ただ即座に解決するという約束をする必要がありますか?

これがあなたのコードに書かれているポイントは、約束のチェーンの中にあります。 throw ingを除いて解決されたPromiseを返すために、(その文脈で)何もする必要はありません。

このプロミスは、undefinedを除き、お客様が返品したいかなる値にも解決いたします。 undefined(明示的にも暗黙的にも)を返すと、このPromiseはPromiseチェーンの最後の値に解決されます。
明示的にに解決する必要がある場合のみ、undefinedにはreturn Promise.resolve()が必要です。

//質問2b:すぐに拒否するために作成する必要がありますか?

依然としてPromiseチェーン内:拒否された値は、同期コードのThrowエラーのようなものなので、ここで行う必要があるのはthrowです。

しかし、あなたが尋ねた文脈ではそれは意味がありません。なぜ、エラーをキャッチする、ちょうどすぐに非常に同じエラーをスローする、そのキャッチブロック内の他の何もせずに。あなたが言うとき、「この約束は、あなたが返す任意の値に解決されます」

function extra_promises_at_start_and_end() { 
    // fake out some module scope variable that indicates if this call is allowed to proceed or not 
    let ok_to_proceed = Math.random() > 0.5 

    if (!ok_to_proceed) { 
     return Promise.reject("failed before starting anything"); 
    } 

    // do 5 things in sequence 
    return another_module_promise_to_do_something(1) 
     .then(() => another_module_promise_to_do_something(2)) 
     .then(() => another_module_promise_to_do_something(3)) 
     .then(() => another_module_promise_to_do_something(4)) 
     .then(() => another_module_promise_to_do_something(5)) 
     .then(() => { 
      // need to do something after the above 5 tasks are done, 

      console.log("doing something after all 5 things are done") 

      return null; //so the previous value is no longer propagated by this Promise 
     }) 
     //.catch(id => { throw id }) //is pointless. 
} 

よう

だからあなたのコードがある可能性があります。それで、新しいPromise((解決、拒絶)=> {解決100})を返すと、... blaw blaw blawは100と同じです。blaw blaw blaw?

正確ではありません。プロミスチェーン内では、100のようなプレーンな値または100 (のようなreturn Promise.resolve(100)結果で同等であるに解決約束...

var foo1 = somePromise.then(() => { 
    //do something 
    return 100 
}) 
//is equivalent in result to 
var foo2 = somePromise.then(() => { 
    //do something 
    return Promise.resolve(100); 
}) 
//or to 
var foo3 = somePromise.then(() => { 
    //do something 
    return new Promise(resolve => resolve(100)); 
}) 

foo1foo2に解決foo3ているすべての約束を返しますsomePromiseの後に値100が終了しました。それは結果と同等です。

...しかし番号にthen()を呼び出すことはできません。私が学んだ

//you can do 
somePromise.then(() => { 
    //do something 
    return 100 
}).then(...) 

//or sometimes you want to do 
somePromise.then((value) => { 
    //usually because you need `value` inside `.then(...)` 
    return somethingAsync().then(...) 
}) 

//but you can NOT do 
somePromise.then(() => { 
    //do something 
    return 100.then(...) 
}) 
+0

@grabbag、厳密にはそうではありません。私はその答えを説明した – Thomas

0

です:

  • Promise.resolve(value)メソッドは、指定された値で解決されプロミスオブジェクトを返します。だから私の機能を呼んでいる人は誰でも応答をすることができます。

  • Promise.reject(reason)メソッドは、指定された理由で拒否されたPromiseオブジェクトを返します。したがって、必要に応じてチェーンが失敗します。

  • これ以降の戻り値はすべて、約束でカプセル化されます。このような気持ちは、意図を隠す。だから使用しないでください。

次のように私の新しい機能は次のとおりです。

function promise_something() { 
    // fake out some module scope variable that indicates if this call is allowed to proceed or not 
     let ok_to_proceed = Math.random() > 0.5 



if (!ok_to_proceed) { 
     return Promise.reject("failed before starting anything") 
    } 

    // do 5 things in sequence 
    return another_module_promise_to_do_something(1).then(() => { 
     return another_module_promise_to_do_something(2) 
    }).then(() => { 
     return another_module_promise_to_do_something(3) 
    }).then(() => { 
     return another_module_promise_to_do_something(4) 
    }).then(() => { 
     return another_module_promise_to_do_something(5) 
    }).then(() => { 
     // need to do something after the above 5 tasks are done, 

     console.log("doing something after all 5 things are done") 

     return Promise.resolve() 
}