Apa yang baru di Node.js 15?

Kami membagikan terjemahan artikel, yang berisi detail tentang fitur-fitur baru dari versi ke-15 Node.js.


Node.js versi 15 dirilis pada 20 Oktober 2020. Perubahan besar meliputi:



  • mode lemparan pada penyimpangan yang tidak tertangani
  • fitur bahasa V8 8.6
  • NPM 7
  • dukungan QUIC eksperimental
  • N-API Versi 7
  • finalisasi Async Local Storage API


Mari kita lihat lebih dekat apa inovasi ini dan bagaimana mereka dapat digunakan.



Menggunakan NVM untuk Ringkasan Node



Di artikel sebelumnya, kami membahas petunjuk untuk menggunakan NVM (Node Version Manager) untuk mengelola versi Node.js dan NPM. Kami memiliki Node.js 12.16.0 dan NPM 6.14.8 terinstal di lingkungan kami. Dengan menjalankan nvm install node , kami telah menginstal Node.js 15.4.0 dan NPM7.0.15.



Kami memiliki dua jendela terbuka, satu dengan Node.js 12 dan yang lainnya dengan Node.js 15.



Di jendela node12 :



$ nvm use 12
Now using node v12.16.0 (npm v6.14.8)
      
      





Di jendela node15 :



$ nvm use 15
Now using node v15.4.0 (npm v7.0.15)
      
      





Kami sekarang dapat menyelidiki versi ini.



Mode lempar pada penolakan janji yang tidak tertangani



Peristiwa unhandledRejection dimunculkan setiap kali sebuah janji ditolak dan penangan error tidak dilampirkan ke janji selama loop peristiwa. Mulai Node.js 15, mode default untuk unhandledRejection telah diubah dari warn ke throw . Dalam mode lemparan , jika hook unhandledRejection tidak disetel, unhandledRejection dilemparkan sebagai pengecualian yang tidak ditangkap oleh metode catch .



Buat program untuk menolak janji dengan pesan kesalahan:



function myPromise() {
  new Promise((_, reject) =>
    setTimeout(
      () =>
        reject({
          error: 'The call is rejected with an error',
        }),
      1000
    )
  ).then((data) => console.log(data.data));
}

myPromise();
      
      





Ketika Anda menjalankan kode ini di jendela node12 , pesan peringatan panjang muncul:



$ node myPromise.js
(node:79104) UnhandledPromiseRejectionWarning: #<Object>
(node:79104) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:79104) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.Users that have an unhandledRejection hook should see no change in behavior, and it’s still possible to switch modes using the --unhandled-rejections=mode process flag.
      
      





Menjalankan kode ini di jendela node15 menghasilkan kesalahan UnhandledPromiseRejection :



$ node myPromise.js
node:internal/process/promises:227
          triggerUncaughtException(err, true /* fromPromise */);
          ^[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "#<Object>".] {
  code: 'ERR_UNHANDLED_REJECTION'
}
      
      





Tambahkan penangan kesalahan ke cabang kemudian dalam kode di bawah ini ( .catch (( error ) => console.log ( error .error)) juga berfungsi).



function myPromise() {
  new Promise((_, reject) =>
    setTimeout(
      () =>
        reject({
          error: 'The call is rejected with an error',
        }),
      1000
    )
  ).then(
    (data) => console.log(data.data),
    (error) => console.log(error.error)
  );
}

myPromise();
      
      





Sekarang kode berjalan dengan benar di kedua jendela ( node12 dan node15 ):



$ node myPromise.js
The call is rejected with an error
      
      





Direkomendasikan untuk menulis penangan error untuk promise. Namun, mungkin ada kasus di mana kesalahan tidak ditangkap oleh metode tangkap. Direkomendasikan untuk menyiapkan hook unhandledRejection untuk mendeteksi potensi kesalahan.



function myPromise() {
  new Promise((_, reject) =>
    setTimeout(
      () =>
        reject({
          error: 'The call is rejected with an error',
        }),
      1000
    )
  ).then((data) => console.log(data.data));
}

myPromise();

process.on('unhandledRejection', (reason, promise) => {
  console.log('reason is', reason);
  console.log('promise is', promise);
  // Application specific logging, throwing an error, or other logic here
});
      
      





The unhandledRejection kait karya di kedua Node.js 12 dan Node.js 15. Setelah diinstal, unhandledRejection yang ditangani sesuai kebutuhan.



$ node myPromise.js
reason is { error: 'The call is rejected with an error' }
promise is Promise { <rejected> { error: 'The call is rejected with an error' } }
      
      





V8 8.6 Fitur bahasa baru



V8, mesin JavaScript, diperbarui dari 8,4 menjadi 8,6. Versi: kapan. Selain berbagai penyesuaian untuk meningkatkan kinerja, V8 baru memiliki fitur-fitur berikut:



  • Promise.any () dan AggregateError (dari V8 8.5)
  • menunggu setTimeout dan AbortController (eksperimental)
  • String.prototype.replaceAll () (dari V8 8.5)
  • Operator penugasan logis && = , || = dan ?? = (dari V8 8.5)


Promise.any () dan AggregateError



Pertama, mari kita lihat metode Promise.all () yang ada .



Promise.all () mengambil iterable dari promise sebagai masukan dan mengembalikan satu promise, yang dieksekusi sebagai larik hasil dari promise masukan.



Program berikut memanggil Promise.all () dengan dua janji yang diselesaikan:



function myPromise(delay) {
  return new Promise((resolve) =>
    setTimeout(
      () =>
        resolve({
          data: The data from ${delay} ms delay,
        }),
      delay
    )
  );
}

async function getData() {
  try {
    const data = await Promise.all([myPromise(5000), myPromise(100)]);
    console.log(data);
  } catch (error) {
    console.log(error);
  }
}

getData();

      
      





Promise.all () mengembalikan janji yang akan dipenuhi ketika semua janji masukan diselesaikan, atau jika iterable tidak berisi janji:



$ node myPromise.js
[
  { data: 'The data from 5000 ms delay' },
  { data: 'The data from 100 ms delay' }
]
      
      





Program berikut memanggil Promise.all () dengan dua janji yang ditolak.



function myPromise(delay) {
  return new Promise((_, reject) =>
    setTimeout(
      () =>
        reject({
          error: The error from ${delay} ms delay,
        }),
      delay
    )
  );
}

async function getData() {
  try {
    const data = await Promise.all([myPromise(5000), myPromise(100)]);
    console.log(data);
  } catch (error) {
    console.log(error);
  }
}

getData();
      
      





Promise.all () langsung menolak penolakan apa pun atas janji input atau kesalahan apa pun pada saat eksekusi, yang mengembalikan pesan tentang kesalahan ini:



$ node myPromise.js
{ error: 'The error from 100 ms delay' }
      
      





Promise.any () adalah metode baru di Node.js 15. Ini kebalikan dari Promise.all () . Promise.any () menerima iterable yang berisi objek Promise. Dan, segera setelah salah satu Promises di iterable berhasil, metode tersebut akan mengembalikan satu promise dengan nilai dari janji yang terpenuhi.



Program berikut memanggil Promise.any () dengan dua janji yang diselesaikan:



function myPromise(delay) {
  return new Promise((resolve) =>
    setTimeout(
      () =>
        resolve({
          data: The error from ${delay} ms delay,
        }),
      delay
    )
  );
}

async function getData() {
  try {
    const data = await Promise.any([myPromise(5000), myPromise(100)]);
    console.log(data);
  } catch (error) {
    console.log(error);
    console.log(error.errors);
  }
}

getData();
      
      





Promise.any () mengembalikan janji terselesaikan pertama:



$ node myPromise.js
{ data: 'The error from 100 ms delay' }
      
      





Program berikut memanggil Promise.any () dengan dua janji yang ditolak:



function myPromise(delay) {
  return new Promise((_, reject) =>
    setTimeout(
      () =>
        reject({
          error: The error from ${delay} ms delay,
        }),
      delay
    )
  );
}

async function getData() {
  try {
    const data = await Promise.any([myPromise(5000), myPromise(100)]);
    console.log(data);
  } catch (error) {
    console.log(error);
    console.log(error.errors);
  }
}

getData();
      
      





Jika janji di iterable gagal, mis. semua janji yang diberikan akan ditolak, janji yang dikembalikan ditolak dengan AggregateError , subclass baru dari Error yang mengelompokkan error individu menjadi satu.



$ node myPromise.js
[AggregateError: All promises were rejected]
[
  { error: 'The error from 5000 ms delay' },
  { error: 'The error from 100 ms delay' }
]
      
      





Tunggu setTimeout dan AbortController



Dalam contoh sebelumnya, kami menggunakan setTimeout di dalam panggilan janji.



SetTimeout di WindowOrWorkerGlobalScope menggunakan callback. Namun, pengatur waktu / janji menyediakan versi setTimeout yang dijanjikan yang dapat digunakan dengan async / await.



const { setTimeout } = require('timers/promises');

async function myPromise(delay) {
  await setTimeout(delay);
  return new Promise((resolve) => {
    resolve({
      data: The data from ${delay} ms delay,
    });
  });
}

async function getData() {
  try {
    const data = await Promise.any([myPromise(5000), myPromise(100)]);
    console.log(data);
  } catch (error) {
    console.log(error);
    console.log(error.errors);
  }
}

getData();
      
      





AbortController adalah objek JavaScript yang memungkinkan Anda untuk membatalkan satu atau lebih permintaan web sesuka hati. Kami telah memberikan contoh penggunaan AbortController di artikel lain tentang useAsync .



Baik menunggu setTimeout dan AbortController adalah fitur eksperimental.



String.prototype.replaceAll ()



Mari kita lihat metode String.prototype.replace () yang ada .



replace () mengembalikan string baru dengan beberapa atau semua kecocokan pola diganti dengan replacer. Polanya bisa berupa string atau ekspresi reguler. Placeholder bisa berupa string atau fungsi yang dipanggil untuk setiap pertandingan.



Jika polanya adalah string, hanya kemunculan pertama yang akan diganti.



'20+1+2+3'.replace('+', '-');
      
      





Menggunakan operator ini akan menghasilkan β€œ20–1 + 2 + 3” .



Untuk mengganti semua "+" dengan "-", Anda perlu menggunakan ekspresi reguler.



'20+1+2+3'.replace(/\+/g, '-');
      
      





Menggunakan operator di atas akan menghasilkan β€œ20-1-2-3” .



Metode replaceAll () baru di Node.js 15. Dengan menggunakannya, kita tidak perlu menggunakan ekspresi reguler. Metode ini mengembalikan string baru dengan semua kecocokan pola diganti dengan placeholder. Polanya bisa berupa string atau ekspresi reguler, dan placeholder bisa berupa string atau fungsi yang dipanggil untuk setiap kecocokan.



Berkat metode replaceAll () , kita tidak perlu menggunakan ekspresi reguler untuk mengganti semua "+" dengan "-".



'20+1+2+3'.replaceAll('+', '-');
      
      





Eksekusi operator ini memberikan β€œ20-1-2-3” .



Operator penugasan logis && =, || = dan ?? =



Operator penugasan logika AND ( x && = y ) melakukan operasi penugasan hanya jika x benar.



x && = y ekuivalen dengan x && (x = y) , tapi tidak sama dengan x = x && y .



let x = 0;
let y = 1;

x &&= 0; // 0
x &&= 1; // 0
y &&= 1; // 1
y &&= 0; // 0
      
      





Operator penugasan logika OR (x || = y) melakukan operasi penugasan hanya jika x salah.



x || = y setara dengan x || (x = y) tetapi tidak setara dengan x = x || di .



let x = 0;
let y = 1;

x ||= 0; // 0
x ||= 1; // 1
y ||= 1; // 1
y ||= 0; // 1
      
      





Operator penugasan logis nullish (x ?? = y) melakukan operasi penugasan hanya jika x adalah NULL ( null atau undefined ).



x ?? = y ekivalen dengan x ?? (x = y) , dan tidak setara dengan x = x ?? di .



let x = undefined;
let y = '';

x ??= null; // null
x ??= 'a value'; // "a value"
y ??= undefined; // ""
y ??= null; // ""
      
      





Perubahan lainnya



Selain mode lemparan pada penolakan janji yang tidak tertangani dan fitur bahasa V8 8.6 baru, Node.js 15 memiliki perubahan berikut:



NPM 7 : Banyak perubahan, termasuk instalasi otomatis dependensi peer, peningkatan paket dan file yarn.lock, dukungan ruang kerja , dll. Semua ini dijelaskan dalam artikel ini sebagai referensi .



QUIC : Dukungan eksperimental untuk lapisan transport UDP, yang merupakan protokol utama untuk HTTP / 3. QUIC mencakup keamanan yang disematkan dengan TLS 1.3, kontrol aliran, koreksi kesalahan, migrasi koneksi, dan multiplexing.



N-API Versi 7: API untuk membuat addons kustom. Ini tidak tergantung pada runtime JavaScript yang mendasarinya dan didukung sebagai bagian dari Node.js.



Peningkatan Async Local Storage API : Memberikan kemampuan untuk logging yang lebih modern dan analisis fitur untuk aplikasi skala besar.



Kesimpulan



Versi baru Node.js 15 memiliki sejumlah besar fitur dan peningkatan baru, termasuk yang cukup signifikan.



Coba versi baru dan bersiaplah untuk memperbarui proyek.



Terima kasih atas perhatiannya! Saya harap artikel ini bermanfaat bagi Anda.



All Articles