2016-11-15 15 views
1

私はそれがすべて約束について考え出したと思ったが、これは実際にベッドから私を捨てる。 2つの引数を取ってエグゼキュータを使って新しいPromiseを作成するとき、私はその約束でthen()またはcatch()を実行する前にこのメソッドを実行しているのですか?私は尋ねる前に約束を実行しないでください

Running node 6.2.2。

import assert = require('assert'); 

describe("When working with promises",() => { 
    let ar = [1, 2, 3, 4, 5, 6]; 

    beforeEach(() => { 

    }) 

    it("should be perfectly fine but isn't when mapping to promises", (done) => { 
     ar.map(num => { 
      return new Promise((resolve, reject) => { 
       done(new Error('Why on earth is ' + num + ' called')); 
      }) 
     }) 

     done(); 
    }) 

    it("should be perfectly fine when mapping to methods", (done) => { 

     ar.map(num => { 
      return (resolve, reject) => { 
       done(new Error(num + ' is not called ever')); 
      } 
     }) 

     done(); 
    }) 
}); 

最初のテストが失敗し、2番目のテストが成功しました。

答えて

5

documentation for Promiseを確認すると、コンストラクタに与えられた関数がすぐにで実行されていることがわかります。非同期計算を開始し、そこに2つのコールバックをインストールすることになっています(つまり、resolverejectは今すぐ呼び出されませんが、計算が完了するか失敗するたびに呼び出されます)。

Promise機能がない非同期計算で、それはちょうどあなたが素敵なパッケージにまとめ、それを追跡する必要があることを計算し、2つのコールバックをラップ(この設定が行われた直後に戻ります)。

2番目の例では、各数値に対して無名関数を作成しますが、いずれの関数も呼び出すことはありません。

私はその約束

あなたはどのハンドラ/チェインをインストールした場合の約束は気にしないで(そして取る)またはキャッチ()のいずれかの前に、なぜこのメソッドが実行されています。誰かが見ているかどうかに関わらず、計算は開始された(または開始されなかった)でしょう。

+0

ありがとう、私はいつもPromiseコンストラクタを複数回実行できると思っていました。できますが、エグゼキュータで実行されるすべての作業は1回だけ実行されます – Lostfields

1

同じ動作を実現するには、工場で約束をラップする必要があります。そのためにラムダ関数を使うことができます。

it("should be perfectly fine but isn't when mapping to promises", (done) => { 
    ar.map(num => { 
     return() => new Promise((resolve, reject) => { 
      done(new Error('Why on earth is ' + num + ' called')); 
     }) 
    }) 

    done(); 
}) 

だから、マップ中に(その実行すぐ)約束を作成せずに、後で呼び出すためにステートレスの工場を持っています。

Promise.allPromise.race、またはカスタムチェーンを使用して、後でバッチ実行するためのcompose and join Promisesを許可します。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
1

[...] executor機能を決意を通過し、プロミス実装によって直ちに実行され、拒否された機能[...]。

これは、プロミスの実装です。新しいプロミスを作成し、プロミスがすでに成功したか失敗したときに後でチェーンthen()またはcatch()ハンドラをアタッチすることもできます。

const p = new Promise(someExecutor); 
// do some other things 
p.then(someHandler); 
// do some other things 
p.catch(someOtherHandler); 

あなたはまだ、executorが実行したくない、まだ、その後、Promise constructurにそれを渡さない場合。

0

前ではなく)「その後、()」ハンドラが装着されている、あなたは、プレーン、その後-ABLES(https://promisesaplus.com/

var runLater = { 
    then: function(resolve, reject) { 
    var p = new Promise (...); // Creating a promise is optional 
    resolve(p); // you can return a plain value 
    } 
} 

を使用することができます(注)このプロミスではないので、「キャッチ」メソッドを持っていません。

しかし、約束を期待任意の関数に与えることができる。

  • `Promise.all([runLater])
  • 次いで=>今.then(function() { return runLater; })
  • Promise.resolve(runLater)を扱うの結果としてリターンthen/catchとの約束です。

いずれもrunLater.thenメソッドを呼び出します。

関連する問題