Janji, berikan parameter tambahan ke rantai kemudian


100

Sebuah janji, misalnya:

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

Setelah kita panggil, barulah metode yang dijanjikan:

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

Fungsi doWork terlihat seperti ini:

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

Bagaimana cara menghindari mengembalikan fungsi dalam di doWork, untuk mendapatkan akses ke data dari parameter teks dan janji? Adakah trik untuk menghindari fungsi batin?


1
Mengapa ada orang yang dengan sengaja menolak kari ? Untuk menggunakan bindmetode mengerikan ? - yang juga sangat lambat.

@ Untuk atau saya tidak mengerti Anda, dapatkah Anda memberikan beberapa kode untuk klarifikasi?
Roland

Jawaban:


86

Anda dapat menggunakan Function.prototype.binduntuk membuat fungsi baru dengan nilai yang diteruskan ke argumen pertamanya, seperti ini

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

dan Anda dapat mengubah doWorkke,

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

Sekarang, textakan benar-benar 'text'masuk doWorkdan dataakan menjadi nilai yang diselesaikan oleh Janji.

Catatan: Pastikan Anda memasang penangan penolakan ke rantai janji Anda.


Program kerja: Salinan langsung di REPL Babel

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

terima kasih, itu membantu, sebelumnya saya mencoba doWork.call (ini, 'teks'), tetapi data diganti dengan 'teks'
pengguna3110667

2
callmemanggil fungsi di tempat, bindmembuat fungsi baru, namun keduanya menerima konteks eksekusi sebagai argumen pertama mereka.
sdgluck

103

Mungkin jawaban yang paling mudah adalah:

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

Atau, karena ini diberi tag ecmascript-6, menggunakan fungsi panah:

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

Menurut saya ini paling mudah dibaca, dan tidak terlalu banyak untuk ditulis.


5

Gunakan kari.

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 berhati-hatilah dengan ini, jika Anda membuat curriedDoWorkjanji dengan melakukan return new Promise()di baris pertama fungsi ini, janji tersebut dijalankan segera setelah Anda memanggil curriedDoWork()(seperti yang Anda lakukan di..then(curriedDoWork('text'))
Flame

@Flame: jawaban singkat, demi kenyamanan Anda, Anda dapat menggabungkan janji ke dalam sebuah fungsi, jika Anda ingin melakukannya.
germain

@yks, Anda dapat menunjukkan sintaks ini yang cukup menarik const curriedWork = text => data => console.log (data + teks)
germain

1
@germain ah ya saya pernah melihat formulir ini sebelumnya, harus menyukai pemrograman fungsional. Namun saya mengalami fungsi panah rusak di beberapa browser, jadi saya cenderung menghindarinya sekarang.
yks

@yks, hanya Internet Explorer yang tidak mendukungnya dan tidak akan pernah, karena Edge, Internet Explorer yang terakhir dibangun adalah 9 Desember 2015. Mari kita lanjutkan ~
germain

0

Lodash menawarkan alternatif yang bagus untuk hal ini.

 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
 }

Atau, jika Anda ingin fungsi sukses hanya memiliki satu parameter (hasil janji yang terpenuhi), Anda dapat menggunakannya dengan cara ini:

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

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

Ini akan melekat text: 'myArgString'pada thiskonteks di dalam fungsi.


0

Jawaban baru untuk pertanyaan ini adalah dengan menggunakan fungsi panah, yang secara otomatis mengikat 'ini' dan jauh lebih mudah dibaca. Google untuk tautan seperti: https://2ality.com/2016/02/arrow-functions-vs-bind.html

Anda bisa mengatur teks seperti ini: this.text = 'text' P. lalu (data => doWork (data)); //this.text di dalam doWork akan dievaluasi menjadi 'text'.

Ini disarankan oleh jib di atas dan bahwa (atau ini!) Harus menjadi jawaban yang diterima sekarang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.