Sözler, daha sonra zincire ek parametreler aktar


100

Bir söz, örneğin:

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

Biz aradıktan sonra, sözdeki yöntem:

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

doWork işlevi şuna benzer:

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

Söz ve metin parametrelerinden verilere erişmek için doWork'te bir iç işlev döndürmekten nasıl kaçınabilirim? İçsel işlevden kaçınmanın püf noktaları var mı?


1
Neden birisi kasıtlı olarak körlemekten vazgeçsin ? İğrenç bindyöntemi kullanmak için mi? - ki bu da son derece yavaştır.

@ftor Seni anlamıyorum, açıklama için biraz kod yazabilir misin?
Roland

Yanıtlar:


86

Function.prototype.bindİlk argümanına aktarılan bir değerle yeni bir işlev oluşturmak için kullanabilirsiniz , bunun gibi

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

ve değiştirebileceğiniz doWorkiçin,

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

Şimdi, textaslında olacaktır 'text'içinde doWorkve dataPromise tarafından çözüldü değer olacaktır.

Not: Lütfen söz zincirinize bir ret işleyicisi eklediğinizden emin olun.


Çalışma programı: Babel'in REPL'inin canlı kopyası

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

teşekkürler, bu yardımcı oldu, daha önce doWork.call'ı (bu, 'metin') denedim, ancak verilerin yerini 'metin' aldı
user3110667

2
callyerinde bir işlevi çağırır, bindyeni bir işlev oluşturur, ancak her ikisi de ilk argümanları olarak bir yürütme bağlamını kabul eder.
sdgluck

103

Belki de en basit cevap şudur:

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

Veya bu etiketlendiğinden ecmascript-6ok işlevlerini kullanarak:

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

Bunu en okunaklı buluyorum ve yazacak kadar da değil.


5

Köri kullanın.

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 buna dikkat edin, eğer bu işlevin ilk satırında curriedDoWorkyaparak bir söz oluşturursanız , söz aradığınız anda yerine getirilir (yaptığınız gibireturn new Promise()curriedDoWork()..then(curriedDoWork('text'))
Alev

@Flame: kısa cevap, eğer isterseniz, rahatınız için sözü bir fonksiyona dönüştürebilirsiniz.
germain

@yks, oldukça ilginç olan bu sözdizimini belirtmiş olabilirsiniz. curriedWork = text => data => console.log (data + text)
germain

1
@germain ah evet bu formu daha önce görmüştüm, işlevsel programlamayı sevmeliyim. Ancak bazı tarayıcılarda ok işlevlerinin bozulduğunu görüyorum, bu yüzden şimdi bundan kaçınma eğilimindeyim.
yks

@yks, yalnızca Internet Explorer bunu desteklemiyor ve Edge nedeniyle asla olmayacak, Internet Explorer'ın son yapısı 9 Aralık 2015'ti. Hadi devam edelim ~
germain

0

Lodash, tam da bu şey için güzel bir alternatif sunuyor.

 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
 }

Veya başarı fonksiyonunuzun yalnızca bir parametresine sahip olmasını istiyorsanız (yerine getirilen vaat sonuçları), şu şekilde kullanabilirsiniz:

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

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

Bu ekler text: 'myArgString'için thisişlev içinde bağlamda.


0

Bu sorunun yeni cevabı, 'bunu' otomatik olarak bağlayan ve çok daha okunaklı olan ok işlevlerini kullanmaktır. Şu gibi bağlantılar için Google: https://2ality.com/2016/02/arrow-functions-vs-bind.html

Metni şu şekilde ayarlayabilirsiniz: this.text = 'text' P.then (data => doWork (data)); //this.text doWork içinde 'metin' olarak değerlendirilir.

Bu, yukarıdaki jib tarafından önerilmektedir ve bu (veya bu!) Şimdi kabul edilen cevap olmalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.