web-dev-qa-db-ja.com

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

約束、例えば:

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);
  }
}

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

86
user3110667

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

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

doWorkを次のように変更できます。

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

これで、textは実際にはdoWork'text'になり、dataはPromiseによって解決された値になります。

注:プロミスチェーンに拒否ハンドラを必ず添付してください。


作業プログラム:バベルの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);
77
thefourtheye

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

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

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

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

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

92
jib

カレーを使用します。

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
);
3
yks

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つだけ(フルフィルメントプロミスの結果)が必要な場合は、次のように使用できます。

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

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

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

0
JellyRaptor