Cepat elakkan perangkap dan bercakap tentang 5 kesilapan biasa dalam menggunakan janji!

青灯夜游
Lepaskan: 2021-12-08 10:22:19
ke hadapan
1877 orang telah melayarinya

Artikel ini akan berkongsi dengan anda 5 kesilapan biasa apabila menggunakan janji untuk membantu anda mengelakkan perangkap dengan cepat.

Cepat elakkan perangkap dan bercakap tentang 5 kesilapan biasa dalam menggunakan janji!

Promise menyediakan cara yang elegan untuk mengendalikan operasi tak segerak dalam JS. Ini juga merupakan penyelesaian untuk mengelakkan "neraka panggilan balik". Walau bagaimanapun, tidak ramai pembangun memahami perkara yang terlibat. Oleh itu, ramai orang cenderung melakukan kesilapan dalam amalan. [Cadangan berkaitan: Tutorial pembelajaran javascript]

Dalam artikel ini, kami memperkenalkan lima kesilapan biasa apabila menggunakan janji, dan berharap semua orang dapat mengelakkan kesilapan ini.

1 Elak Janji Neraka

Biasanya Janji digunakan untuk mengelakkan panggilan balik neraka. Tetapi menyalahgunakan mereka juga boleh menyebabkan Janji menjadi neraka.

userLogin('user').then(function(user){
    getArticle(user).then(function(articles){
        showArticle(articles).then(function(){
            //Your code goes here...
        });
    });
});
Salin selepas log masuk

Dalam contoh di atas, kami mempunyai tiga janji bersarang untuk userLogin, getararticle dan showararticle. Dengan cara ini kerumitan akan berkembang mengikut perkadaran dengan baris kod dan ia mungkin menjadi tidak boleh dibaca.

Untuk mengelakkan perkara ini, kita perlu membuka sarang kod, mengembalikan then daripada yang pertama getArticle dan kemudian mengendalikannya dalam then kedua.

userLogin('user')
  .then(getArticle)
  .then(showArticle)
  .then(function(){
       //Your code goes here...
});
Salin selepas log masuk

2 Gunakan <span style="font-size: 18px;">try/catch</span>cuba/tangkap sekat

dalam Promise <. 🎜>

Biasanya, kami menggunakan try/catch blok untuk mengendalikan ralat. Walau bagaimanapun, menggunakan Promise di dalam objek try/catch tidak disyorkan.

Ini kerana objek Promise akan dikendalikan secara automatik dalam catch jika terdapat sebarang ralat.

ew Promise((resolve, reject) => {
  try {
    const data = doThis();
    // do something
    resolve();
  } catch (e) {
    reject(e);
  }
})
  .then(data => console.log(data))
  .catch(error => console.log(error));
Salin selepas log masuk

Dalam contoh di atas, kami menggunakan blok try/catch di dalam Promise.

Walau bagaimanapun, Janji itu sendiri akan menangkap semua kesilapan (walaupun kesilapan taip) dalam skopnya, tanpa memerlukan blok try/catch. Ia memastikan bahawa semua pengecualian yang dilemparkan semasa pelaksanaan ditangkap dan ditukar menjadi Janji yang ditolak.

new Promise((resolve, reject) => {
  const data = doThis();
  // do something
  resolve()
})
  .then(data => console.log(data))
  .catch(error => console.log(error));
Salin selepas log masuk

Nota: Adalah penting untuk menggunakan blok .catch() dalam blok Promise. Jika tidak, kes ujian anda mungkin gagal dan aplikasi mungkin ranap semasa fasa pengeluaran.

3. Gunakan fungsi tak segerak dalam blok Promise

Async/Await ialah sintaks yang lebih maju untuk mengendalikan kod segerak Berbilang Janji. Apabila kita menggunakan kata kunci async sebelum pengisytiharan fungsi, ia akan mengembalikan Janji Kita boleh menggunakan kata kunci await untuk menghentikan kod sehingga Janji yang kita tunggu diselesaikan atau ditolak.

Walau bagaimanapun, apabila anda meletakkan fungsi Async di dalam blok Promise, akan terdapat beberapa kesan sampingan.

Andaikan kami ingin melakukan operasi tak segerak dalam blok Promise, jadi kami menggunakan kata kunci async, tetapi malangnya kod kami menimbulkan ralat.

Dengan cara ini, kami tidak dapat menangani ralat dengan segera walaupun menggunakan blok catch() atau menunggu Janji anda di dalam blok try/catch. Sila lihat contoh di bawah.

// 此代码无法处理错误
new Promise(async () => {
  throw new Error(&#39;message&#39;);
}).catch(e => console.log(e.message));

(async () => {
  try {
    await new Promise(async () => {
      throw new Error(&#39;message&#39;);
    });
  } catch (e) {
    console.log(e.message);
  }
})();
Salin selepas log masuk

Apabila saya menemui fungsi async di dalam blok Promise, saya cuba mengekalkan logik async di luar blok Promise untuk memastikan ia disegerakkan. Ia berfungsi 9 kali daripada 10.

Walau bagaimanapun, dalam sesetengah kes, fungsi async mungkin diperlukan. Dalam kes ini, tiada pilihan selain mengurusnya secara manual menggunakan blok try/catch.

new Promise(async (resolve, reject) => {
  try {
    throw new Error(&#39;message&#39;);
  } catch (error) {
    reject(error);
  }
}).catch(e => console.log(e.message));


//using async/await
(async () => {
  try {
    await new Promise(async (resolve, reject) => {
      try {
        throw new Error(&#39;message&#39;);
      } catch (error) {
        reject(error);
      }
    });
  } catch (e) {
    console.log(e.message);
  }
})();
Salin selepas log masuk

4 Laksanakan blok Promise dengan segera selepas mencipta Promise

Bagi coretan kod di bawah, jika kita meletakkan kod tersebut coretan dalam Di mana sahaja permintaan HTTP dipanggil, ia dilaksanakan serta-merta.

const myPromise = new Promise(resolve => {
  // code to make HTTP request
  resolve(result);
});
Salin selepas log masuk

Sebabnya ialah kod ini dibalut dengan pembina Promise. Walau bagaimanapun, sesetengah mungkin berpendapat bahawa ia hanya dicetuskan selepas melaksanakan kaedah myPromise then.

Walau bagaimanapun, ini tidak berlaku. Sebaliknya, apabila Janji dibuat, panggilan balik dilaksanakan serta-merta.

Ini bermakna apabila baris berikut dicapai selepas membina myPromise, kemungkinan besar permintaan HTTP sudah berjalan atau sekurang-kurangnya dalam keadaan berjadual.

Janji sentiasa bersemangat untuk melaksanakan proses.

Tetapi apakah yang perlu saya lakukan jika saya ingin melaksanakan Janji pada masa hadapan? Bagaimana jika saya tidak mahu membuat permintaan HTTP sekarang? Adakah terdapat beberapa mekanisme ajaib yang terbina dalam Janji yang membolehkan kita melakukan ini?

Jawapannya ialah menggunakan fungsi. Fungsi adalah mekanisme yang memakan masa. Ia hanya akan dilaksanakan jika pembangun memanggilnya secara eksplisit dengan (). Hanya mentakrifkan fungsi tidak membawa kita ke mana-mana. Jadi, cara paling berkesan untuk membuat Janji malas adalah dengan membungkusnya dalam fungsi!

const createMyPromise = () => new Promise(resolve => {
  // HTTP request
  resolve(result);
});
Salin selepas log masuk

对于HTTP请求,Promise 构造函数和回调函数只有在函数被执行时才会被调用。所以现在我们有一个懒惰的Promise,只有在我们需要的时候才会执行。

5. 不一定使用 Promise.all() 方法

如果你已经工作多年,应该已经知道我在说什么了。如果有许多彼此不相关的 Promise,我们可以同时处理它们。

Promise 是并发的,但如你一个一个地等待它们,会太费时间,Promise.all()可以节省很多时间。

记住,Promise.all() 是我们的朋友
const { promisify } = require(&#39;util&#39;);
const sleep = promisify(setTimeout);

async function f1() {
  await sleep(1000);
}

async function f2() {
  await sleep(2000);
}

async function f3() {
  await sleep(3000);
}


(async () => {
  console.time(&#39;sequential&#39;);
  await f1();
  await f2();
  await f3();
  console.timeEnd(&#39;sequential&#39;);  
})();
Salin selepas log masuk

上述代码的执行时间约为 6 秒。但如果我们用 Promise.all() 代替它,将减少执行时间。

(async () => {
    console.time(&#39;concurrent&#39;);
    await Promise.all([f1(), f2(), f3()]);
    console.timeEnd(&#39;concurrent&#39;); 
  })();
Salin selepas log masuk

总结

在这篇文章中,我们讨论了使用 Promise 时常犯的五个错误。然而,可能还有很多简单的问题需要仔细解决。

如果你还有更多相关的错误,欢迎留言一起讨论。

英文原文地址:https://blog.bitsrc.io/5-common-mistakes-in-using-promises-bfcc4d62657f

作者:Ravidu Perera

更多编程相关知识,请访问:编程入门!!

Atas ialah kandungan terperinci Cepat elakkan perangkap dan bercakap tentang 5 kesilapan biasa dalam menggunakan janji!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:segmentfault.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan