Rumah  >  Artikel  >  Tutorial CMS  >  Menggunakan kaedah Promise.all() dan Promise.allSettled() dalam JavaScript

Menggunakan kaedah Promise.all() dan Promise.allSettled() dalam JavaScript

WBOY
WBOYasal
2023-08-30 21:05:201462semak imbas

Menggunakan kaedah Promise.all() dan Promise.allSettled() dalam JavaScript

Tutorial ini akan mengajar anda cara menggunakan Promise menanti dalam JavaScript.

Dalam tutorial ini, saya akan mengajar anda tentang kaedah Promise.all() dan Promise.allSettled() dan cara menggunakannya untuk mengendalikan berbilang Janji. Promise.all()Promise.allSettled() 方法以及如何使用它们来处理多个 Promise。

使用 Promise.all() 方法

Promise 对象具有三个有用的方法,名为 then()catch()finally(),您可以使用它们在 Promise 完成时执行回调方法。 p>

Promise.all() 方法是一个静态方法,这意味着它属于整个类,而不是绑定到该类的任何特定实例。它接受可迭代的 Promise 作为输入并返回单个 Promise 对象。

正如我之前提到的,Promise.all() 方法返回一个新的 Promise。如果传递给该方法的所有承诺都已成功解析,则此新承诺将解析为已确定承诺值的数组。一旦通过的承诺之一被拒绝,这个新的承诺也将被拒绝。

所有 Promise 均成功解决

以下是 Promise.all() 方法的示例,其中所有 Promise 均已成功解析:

const promise_a = new Promise((resolve) => {
  setTimeout(() => {
    resolve('Loaded Textures');
  }, 3000);
});

const promise_b = new Promise((resolve) => {
    setTimeout(() => {
      resolve('Loaded Music');
    }, 2000);
});

const promise_c = new Promise((resolve) => {
    setTimeout(() => {
      resolve('Loaded Dialogues');
    }, 4000);
});


const promises = [
  promise_a, promise_b, promise_c
];

console.log('Hello, Promises!');

Promise.all(promises).then((values) => {
  console.log(values);
  console.log('Start the Game!');
});

/* Output

19:32:06 Hello, Promises!
19:32:10 Array(3) [ "Loaded Textures", "Loaded Music", "Loaded Dialogues" ]
19:32:10 Start the Game!

*/

我们在调用 Promise.all() 方法之前的语句记录于 19:32:06。此外,我们的第三个 Promise 名为 promise_c 需要最长的时间才能解决,并在 4 秒后解决。这意味着调用 all() 方法返回的 Promise 也应该需要 4 秒才能解析。我们可以通过将回调函数传递给 then() 方法来验证是否需要 4 秒才能解析。

这里需要注意的另一件重要事情是,返回的已完成值数组包含这些值的顺序与我们将 Promise 传递给 Promise.all() 方法的顺序相同。名为 promise_b 的 Promise 解析速度最快,只需 2 秒。但是,其解析值仍然位于返回数组中的第二个位置。这与我们将 Promise 传递给 Promise.all() 方法的位置相匹配。

这种秩序的维护在某些情况下非常有帮助。例如,假设您正在使用十个不同的 Promise 获取有关十个不同城市的天气信息。所有这些问题不会同时得到解决,而且不可能事先知道它们的解决顺序。但是,如果您知道数据按照传递 Promise 的顺序返回,您将能够正确分配它以供以后操作。

一个承诺被拒绝

以下是其中一个承诺被拒绝的示例:

const promise_a = new Promise((resolve) => {
  setTimeout(() => {
    resolve('Loaded Textures');
  }, 3000);
});

const promise_b = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error('Could Not Load Music'));
    }, 2000);
});

const promise_c = new Promise((resolve) => {
    setTimeout(() => {
      resolve('Loaded Dialogues');
    }, 4000);
});


const promises = [
  promise_a, promise_b, promise_c
];

console.log('Hello, Promises!');

Promise.all(promises).catch((error) => {
  console.error(error.message);
  console.log('Stop the Game!');
});

/* Output

20:03:43 Hello, Promises!
20:03:45 Could Not Load Music
20:03:45 Stop the Game!

*/

同样,我们在调用 all() 方法之前的语句记录于 20:03:43。然而,我们的第二个承诺 promise_b 这次以拒绝告终。我们可以看到 promise_b 在 2 秒后被拒绝。这意味着 all() 方法返回的 Promise 也应该在 2 秒后拒绝,并出现与我们的 promise_b 相同的错误。从输出中可以明显看出,这正是发生的情况。

await 关键字一起使用

您可能已经知道 await 关键字用于等待承诺解决,然后再继续下一步。我们还知道 all() 方法返回一个承诺。这意味着我们可以使用 await 以及对 Promise.all() 方法的调用。

唯一要记住的是,由于 await 仅在异步函数和模块内有效,因此我们必须将代码包装在异步函数内,如下所示:

function create_promise(data, duration) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(data);
    }, duration);
  });
}

const promise_a = create_promise("Loaded Textures", 3000);
const promise_b = create_promise("Loaded Music", 2000);
const promise_c = create_promise("Loaded Dialogue", 4000);

const my_promises = [promise_a, promise_b, promise_c];

async function result_from_promises(promises) {
  let loading_status = await Promise.all(promises);
  console.log(loading_status);
}

result_from_promises(my_promises);

/* Outputs

08:50:43 Hello, Promises!
08:50:47 Array(3) [ "Loaded Textures", "Loaded Music", "Loaded Dialogue" ]

*/

这一次,我们定义了一个名为 create_promise() 的函数,它根据提供的数据和持续时间为我们创建承诺。我们的异步 result_from_promises() 函数使用 await 关键字来等待 Promise 解析。

使用 Promise.allSettled() 方法

当您只想在所有承诺成功解决后继续操作时,使用 Promise.all() 方法是有意义的。例如,当您加载游戏资源时,这可能很有用。

但是,假设您正在获取有关不同城市天气的信息。在这种情况下,您可以输出获取数据成功的所有城市的天气信息,并输出获取数据失败的错误消息。

Promise.allSettled()

Gunakan kaedah Promise.all()

Objek Promise mempunyai tiga kaedah berguna bernama then(), catch() dan finally() , anda boleh menggunakannya untuk melaksanakan kaedah panggil balik apabila Janji selesai. #🎜🎜#Kaedah Promise.all() ialah kaedah statik, yang bermaksud ia tergolong dalam keseluruhan kelas dan tidak terikat kepada mana-mana contoh kelas tertentu. Ia menerima Janji yang boleh diubah sebagai input dan mengembalikan satu objek Janji. #🎜🎜# #🎜🎜#Seperti yang saya nyatakan sebelum ini, kaedah Promise.all() mengembalikan Janji baharu. Jika semua janji yang diserahkan kepada kaedah ini telah berjaya diselesaikan, janji baharu ini akan diselesaikan kepada pelbagai nilai janji yang ditentukan. Apabila salah satu janji yang diluluskan ditolak, janji baru ini juga akan ditolak. #🎜🎜#

Semua Janji berjaya diselesaikan

#🎜🎜#Berikut ialah contoh kaedah Promise.all() di mana semua Janji berjaya diselesaikan: #🎜🎜#
function create_promise(city) {
  let random_number = Math.random();
  
  let duration = Math.floor(Math.random()*5)*1000;

  return new Promise((resolve, reject) => {
    if (random_number < 0.8) {
      setTimeout(() => {
        resolve(`Show weather in ${city}`);
      }, duration);
    } else {
      setTimeout(() => {
        reject(`Data unavailable for ${city}`);
      }, duration);
    }
  });
}

const promise_a = create_promise("Delhi");
const promise_b = create_promise("London");
const promise_c = create_promise("Sydney");

const my_promises = [create_promise("Delhi"), create_promise("London"), create_promise("Sydney"), create_promise("Rome"), create_promise("Las Vegas")];

async function result_from_promises(promises) {
  let loading_status = await Promise.allSettled(promises);
  console.log(loading_status);
}

result_from_promises(my_promises);

/* Outputs

[
  {
    "status": "fulfilled",
    "value": "Show weather in Delhi"
  },
  {
    "status": "fulfilled",
    "value": "Show weather in London"
  },
  {
    "status": "fulfilled",
    "value": "Show weather in Sydney"
  },
  {
    "status": "rejected",
    "reason": "Data unavailable for Rome"
  },
  {
    "status": "fulfilled",
    "value": "Show weather in Las Vegas"
  }
]

*/
#🎜🎜#Pernyataan sebelum kami memanggil kaedah Promise.all() telah direkodkan pada 19:32:06. Selain itu, Janji ketiga kami bernama promise_c mengambil masa paling lama untuk diselesaikan, diselesaikan selepas 4 saat. Ini bermakna Janji yang dikembalikan dengan memanggil kaedah all() juga perlu mengambil masa 4 saat untuk diselesaikan. Kami boleh mengesahkan sama ada masa 4 saat untuk diselesaikan dengan menghantar fungsi panggil balik ke kaedah then(). #🎜🎜# #🎜🎜#Satu lagi perkara penting yang perlu diperhatikan di sini ialah tatasusunan nilai yang telah dilengkapkan yang dikembalikan mengandungi nilai dalam susunan yang sama di mana kami menyerahkan Promise kepada kaedah Promise.all() . Janji bernama promise_b adalah yang paling cepat diselesaikan, hanya mengambil masa 2 saat. Walau bagaimanapun, nilai yang dihuraikannya masih berada di kedudukan kedua dalam tatasusunan yang dikembalikan. Ini sepadan dengan tempat kami menyerahkan Promise kepada kaedah Promise.all(). #🎜🎜# #🎜🎜#Penyelenggaraan pesanan jenis ini boleh sangat membantu dalam sesetengah situasi. Sebagai contoh, katakan anda menggunakan sepuluh Janji yang berbeza untuk mendapatkan maklumat cuaca tentang sepuluh bandar yang berbeza. Semua masalah ini tidak akan diselesaikan secara serentak, dan adalah mustahil untuk mengetahui terlebih dahulu urutan di mana ia akan diselesaikan. Walau bagaimanapun, jika anda tahu bahawa data dikembalikan dalam susunan Janji diluluskan, anda akan dapat memperuntukkannya dengan betul untuk operasi kemudian. #🎜🎜#

Satu janji telah ditolak

#🎜🎜#Berikut adalah contoh salah satu janji yang ditolak: #🎜🎜# rrreee #🎜🎜#Begitu juga, kenyataan sebelum kita memanggil kaedah all() direkodkan pada 20:03:43. Walau bagaimanapun, janji kedua kami promise_b akhirnya ditolak kali ini. Kita dapat melihat bahawa promise_b ditolak selepas 2 saat. Ini bermakna Janji yang dikembalikan oleh kaedah all() juga harus ditolak selepas 2 saat dengan ralat yang sama seperti promise_b kami. Ia jelas dari output bahawa ini adalah apa yang berlaku. #🎜🎜#

Digunakan dengan kata kunci menunggu

#🎜🎜#Anda mungkin sudah tahu bahawa kata kunci menunggu digunakan untuk menunggu janji diselesaikan sebelum meneruskan ke langkah seterusnya. Kami juga tahu bahawa kaedah all() mengembalikan janji. Ini bermakna kita boleh menggunakan menunggu bersama-sama dengan panggilan ke kaedah Promise.all(). #🎜🎜# #🎜🎜#Satu-satunya perkara yang perlu diingat ialah kerana menunggu hanya sah di dalam fungsi dan modul tak segerak, kita perlu membungkus kod di dalam fungsi tak segerak seperti ini: #🎜🎜# rrreee #🎜🎜#Kali ini, kami mentakrifkan fungsi yang dipanggil create_promise() yang mencipta janji untuk kami berdasarkan data dan tempoh yang diberikan. Fungsi result_from_promises() tak segerak kami menggunakan kata kunci menunggu untuk menunggu Janji diselesaikan. #🎜🎜#

Gunakan kaedah Promise.allSettled()

#🎜🎜#Menggunakan kaedah Promise.all() masuk akal apabila anda hanya mahu meneruskan selepas semua janji berjaya diselesaikan. Ini mungkin berguna, contohnya, apabila anda memuatkan aset permainan. #🎜🎜# #🎜🎜#Tetapi andaikan anda mendapat maklumat tentang cuaca di bandar yang berbeza. Dalam kes ini, anda boleh mengeluarkan maklumat cuaca untuk semua bandar tempat pemerolehan data berjaya dan mengeluarkan mesej ralat jika pemerolehan data gagal. #🎜🎜# Kaedah #🎜🎜#Promise.allSettled() berfungsi paling baik dalam kes ini. Kaedah ini menunggu semua komitmen yang diluluskan untuk diselesaikan melalui resolusi atau penolakan. Janji yang dikembalikan oleh kaedah ini mengandungi tatasusunan objek yang mengandungi maklumat tentang hasil setiap Janji. #🎜🎜#
function create_promise(city) {
  let random_number = Math.random();
  
  let duration = Math.floor(Math.random()*5)*1000;

  return new Promise((resolve, reject) => {
    if (random_number < 0.8) {
      setTimeout(() => {
        resolve(`Show weather in ${city}`);
      }, duration);
    } else {
      setTimeout(() => {
        reject(`Data unavailable for ${city}`);
      }, duration);
    }
  });
}

const promise_a = create_promise("Delhi");
const promise_b = create_promise("London");
const promise_c = create_promise("Sydney");

const my_promises = [create_promise("Delhi"), create_promise("London"), create_promise("Sydney"), create_promise("Rome"), create_promise("Las Vegas")];

async function result_from_promises(promises) {
  let loading_status = await Promise.allSettled(promises);
  console.log(loading_status);
}

result_from_promises(my_promises);

/* Outputs

[
  {
    "status": "fulfilled",
    "value": "Show weather in Delhi"
  },
  {
    "status": "fulfilled",
    "value": "Show weather in London"
  },
  {
    "status": "fulfilled",
    "value": "Show weather in Sydney"
  },
  {
    "status": "rejected",
    "reason": "Data unavailable for Rome"
  },
  {
    "status": "fulfilled",
    "value": "Show weather in Las Vegas"
  }
]

*/

如您所见,数组中的每个对象都包含一个 status 属性,让我们知道承诺是否已实现或被拒绝。在履行承诺的情况下,它包含 value 属性中的解析值。在被拒绝的 Promise 的情况下,它在 reason 属性中包含拒绝的原因。

最终想法

我们了解了 Promise 类的两个有用方法,它们可以让您同时处理多个 Promise。当您想要在其中一个 Promise 被拒绝后立即停止等待其他 Promise 解决时, Promise.all() 方法很有用。当您想要等待所有承诺解决时,无论其解决或拒绝状态如何, Promise.allSettled() 方法非常有用。

Atas ialah kandungan terperinci Menggunakan kaedah Promise.all() dan Promise.allSettled() dalam JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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