約束、追加のパラメーターをチェーンに渡します


100

たとえば、約束:

var P = new Promise(function (resolve, reject) {
  var a = 5;
  if (a) {
    setTimeout(function(){
      resolve(a);
    }, 3000);
  } else {
    reject(a);
  }
});

呼び出した後、promiseのメソッド:

P.then(doWork('text'));

doWork関数は次のようになります。

function doWork(data) {
  return function(text) {
    // sample function to console log
    consoleToLog(data);
    consoleToLog(b);
  }
}

doWorkで内部関数を返さないようにして、promiseおよびtextパラメーターからデータにアクセスするにはどうすればよいですか?内部機能を回避するためのトリックはありますか?


1
なぜ誰かがカレーを故意にやめるのですか?恐ろしいbind方法を使用するために?-これも非常に遅いです。

@ftorわかりません。説明のためにコードを提供していただけますか?
Roland

回答:


86

Function.prototype.bindこのように、最初の引数に値が渡される新しい関数を作成するために使用できます

P.then(doWork.bind(null, 'text'))

あなたが変更することができますdoWorkし、

function doWork(text, data) {
  consoleToLog(data);
}

今、text実際'text'doWorkなりdata、約束によって解決される値になります。

注:必ず、プロジェクションチェーンに拒否ハンドラをアタッチしてください。


作業プログラム: BabelのREPLのライブコピー

function doWork(text, data) {
  console.log(text + data + text);
}

new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
      setTimeout(function () {
        resolve(a);
      }, 3000);
    } else {
      reject(a);
    }
  })
  .then(doWork.bind(null, 'text'))
  .catch(console.error);

おかげで、それは役立ちます、以前に私はdoWork.call(this、 'text')を試しますが、データは 'text'に置き換えられました
user3110667

2
call関数をインプレースで呼び出し、bind新しい関数を作成しますが、どちらも最初の引数として実行コンテキストを受け入れます。
sdgluck

103

おそらく最も簡単な答えは次のとおりです。

P.then(function(data) { return doWork('text', data); });

または、これはタグ付けされているecmascript-6ので、矢印関数を使用します:

P.then(data => doWork('text', data));

私はこれが最も読みやすく、書きすぎないようにしています。


5

カレーを使う。

var P = new Promise(function (resolve, reject) {
    var a = 5;
    if (a) {
        setTimeout(function(){
            resolve(a);
        }, 3000);
    } else {
        reject(a);
    }
});

var curriedDoWork = function(text) {
    return function(data) {
        console.log(data + text);
    }
};

P.then(curriedDoWork('text'))
.catch(
    //some error handling
);

あなたが作成した場合、Bこれには注意してください、curriedDoWork実行して約束にreturn new Promise()この関数の最初の行に、約束をするとすぐに呼び出すように実行されるcurriedDoWork()あなたが行うように(..then(curriedDoWork('text'))

@Flame:短い答えです。必要に応じて、約束を関数にラップできます。
ジェルマン

@yks、非常に興味深いこの構文を示すことができましたconst curriedWork = text => data => console.log(data + text)
germain

1
@germainああ、はい、このフォームを以前に見たことがあります。関数型プログラミングが大好きです。ただし、一部のブラウザーでは矢印機能が壊れるので、今は回避する傾向があります。
yk、2018年

なぜならエッジの@yks、Internet Explorerのみがそれをサポートしていないし、決してない、Internet Explorerの最後のビルドは〜12月9日2015年レッツ・動きだった
ジェルマン

0

Lodashは、これとまったく同じことを行うための優れた代替手段を提供します。

 P.then(_.bind(doWork, 'myArgString', _));

 //Say the promise was fulfilled with the string 'promiseResults'

 function doWork(text, data) {
     console.log(text + " foo " + data);
     //myArgString foo promiseResults
 }

または、成功関数にパラメーターを1つだけ持たせたい場合(満たされたpromise結果)、次のように使用できます。

P.then(_.bind(doWork, {text: 'myArgString'}));

function doWork(data) {
    console.log(data + " foo " + this.text);
    //promiseResults foo myArgString
}

これは関数内のコンテキストにアタッチさtext: 'myArgString'thisます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.