Saya memiliki array fungsi javascript Functs = [f1, f2, f3...] dan saya ingin mengulang array, menjalankan setiap fungsi secara berurutan.

Edit: Saat ini, kami memiliki fungsi yang dipanggil secara eksplisit dalam loop while(true){f1(a,b,c); f2(b); f3(c)...}. Namun, kami ingin membuat jalur pipa ini dapat diperpanjang sehingga pengguna dapat menyisipkan fungsi khusus ke dalam jalur pipa pada tahap apa pun dengan menyediakan metode publik untuk menyisipkan item ke dalam larik, yang menghasilkan: while(true){f1(a,b,c); f2(b); fCustom(b,c); f3(c)...}. Jadi, saluran pipa yang dapat diedit secara eksternal. Mungkin ada cara yang lebih baik untuk melakukan ini, tetapi array fungsi yang dapat diedit tampaknya merupakan cara yang paling mudah.

Masalahnya, setiap fungsi memiliki tanda tangan yang berbeda dan membutuhkan input yang berbeda seperti:

f1 = function(name, address, date) {};
f2 = function(name, age) {};
f3 = function(height);

Dan fungsinya akan dilingkari seperti ini:

mainFunction() {

  let name = something;
  let address = something;
  let date = something;
  ....
  let height = something;

  while(condition == true) {
    for(f in Functs) {
      f(?????); //Each f() has a different signature?
    } 
  }
}

Bagaimana cara memastikan saya dapat meneruskan parameter yang diperlukan ke setiap fungsi? Saya sedang memikirkan sesuatu seperti ini dengan objek parameter dan membungkus fungsi di dalamnya, tetapi tidak tahu seberapa bersih itu. Setidaknya fungsi dapat menyimpan tanda tangan unik mereka, tetapi ini masih tampak seperti sampah.

Edit: Mengingat daftar nilai (nama, usia, tanggal, dll.), setiap fungsi memproses blok data ini dalam alur berurutan. Mungkin satu fungsi memeriksa nilai age dan jika memenuhi kondisi tertentu, ubah date. Fungsi berikutnya akan melihat fungsi name dan date dan memanipulasinya dengan cara tertentu, lalu menimpa name dengan hasilnya. Sampai satu tahap dalam pipa (mungkin setelah beberapa loop) mendeteksi bahwa semuanya telah diproses sepenuhnya. Jadi setiap tahap harus dapat mengubah parameter ini agar perubahannya dapat dilihat oleh fungsi berikutnya dalam urutan, yaitu:f2 = function(height) {height += 2;} f3 = function(name, age, height){if(height > age) condition = false;}

mainFunction() {
  let params = {
    name : something,
    address : something,
    date : something,
    ...
    height : something
  };

  f1 = function(params) {
    f1Inner = function (params.name, params.address, params.date) {};
  }

  Functs = [f1, f2, f3...]

  while(condition == true) {
    for(f in Functs) {
      f(params);
    } 
  }
}
1
Trevor Buckner 11 Desember 2020, 20:02

2 jawaban

Saya akan mengubah fungsi untuk menerima satu argumen sebagai objek, yang dirusak, sehingga semua fungsi dapat dipanggil dengan argumen yang sama:

mainFunction() {
  let name = something;
  let address = something;
  let date = something;
  ....
  let height = something;
  const paramsObj = { name, address, date, height };
  for (const fn of Functs) {
    fn(paramsObj);
    // do whatever you need to do with the return value or loop logic
  }

Dan

f1 = function({ name, address, date }) {};
f2 = function({ name, age }) {};
f3 = function({ height });

Jika Anda ingin parameter ini dimodifikasi saat diteruskan juga, Anda dapat merusak struktur pada baris pertama, memungkinkan Anda untuk mengubah objek params, misalnya:

f1 = function(params) {
  const { name, address, date } = params;
  if (someCondition) {
    params.height += 2;
  }
};

Dan kemudian panggilan berikutnya akan melihat parameter yang diubah.

2
CertainPerformance 11 Desember 2020, 17:09
const if_then = (if_fn, then_fn) => (params_object) =>
  if_fn(params_object) ? then_fn(params_object) : null;

const apply_params = (fn, arg_keys, write_to_key = false) => (params_object) => {
  const result = fn(...arg_keys.map((v) => params_object[v]));
  if(write_to_key)
    params_object[write_to_key] = result;
  return result;
};

const name_and_age = (name, age) => name + ' is ' + age + ' and a half years old';
const volume = (height, width, depth) => height * width * depth;
const double_height = (height) => height * 2;
const double_width = (width) => width * 2;

const count_loop = (params_object) => Object.assign(params_object, { loop_count: (params_object.loop_count ?? 0) + 1 })

let functs = [
  count_loop,
  apply_params(double_height, ['height'], 'height'),
  if_then(
    (p) => !p.name_and_age,
    apply_params(name_and_age, ['name', 'age'], 'name_and_age'),
  ),
];

const bob = true;
if(bob)
  functs.push(
    if_then(
      (p) => p.loop_count > 2,
      apply_params(double_width, ['width'], 'width'),
    )
  );

functs = functs.concat([
  apply_params(volume, ['height', 'width', 'depth'], 'volume'),
  console.log
]);

let params = {
  name : 'Orbold the Grim',
  age : 145,
  height: 2,
  width: 0.3,
  depth: 0.2,
};

const should_exit_loop = (params_object) =>
  (params_object.loop_count || 0) > 10 || params_object.height > 8;

while(!should_exit_loop(params)) {
  functs.forEach(
    (f) => f(params)
  );
};
2
Ben Stephens 12 Desember 2020, 12:19