Maison  >  Article  >  interface Web  >  Qu’est-ce que la promesse dans ECMAScript6 ? A quoi ça sert ? (avec des exemples)

Qu’est-ce que la promesse dans ECMAScript6 ? A quoi ça sert ? (avec des exemples)

不言
不言avant
2018-10-24 11:44:472003parcourir

Le contenu de cet article porte sur ce qu'est Promise dans ECMAScript6 ? A quoi ça sert ? (Avec des exemples), il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.

Je viens de terminer mes études et j'ai une impression approximative. Organisez-le et enregistrez-le pour une étude ultérieure et complétez-le pour approfondir votre compréhension.

Qu'est-ce que Promise

Promise est un constructeur qui peut générer des objets Promise via new.

À quoi sert la promesse

Mon sentiment actuel est le suivant : il est plus pratique de faire fonctionner des processus asynchrones, le processus de contrôle des événements est plus clair et plus intuitif, et il peut être appelé en chaînes

Fonctionnalités de promesse

Extrait de ES6 Getting Started

Les objets de promesse ont les deux fonctionnalités suivantes.
(1) L'état de l'objet n'est pas affecté par le monde extérieur. L'objet Promise représente une opération asynchrone et a trois états : en attente (en cours), exécuté (réussi) et rejeté (échoué). Seul le résultat de l’opération asynchrone peut déterminer l’état actuel, et aucune autre opération ne peut modifier cet état. C'est aussi l'origine du nom Promise. Sa signification anglaise est « engagement », ce qui signifie qu'il ne peut pas être modifié par d'autres moyens.
(2) Une fois le statut modifié, il ne changera plus, et ce résultat peut être obtenu à tout moment. Il n’existe que deux possibilités pour que l’état d’un objet Promise change : de en attente à exécuté et de en attente à rejeté. Tant que ces deux situations se produiront, l’État se solidifiera, ne changera plus et maintiendra ce résultat. résolu. Si le changement a déjà eu lieu, si vous ajoutez une fonction de rappel à l'objet Promise, vous obtiendrez le résultat immédiatement. C'est complètement différent d'un événement. La caractéristique d'un événement est que si vous le manquez et l'écoutez à nouveau, vous n'obtiendrez pas le résultat.

Comprenez-le à travers quelques exemples simples

Construisez un objet Promise simple via de nouveaux

let p = new Promise((resolve, reject) => {});

Les deux paramètres transmis sont utilisés pour contrôler l'état de l'objet Promise , imprimons p pour voir son statut :
Promise {__proto__: Promise[[PromiseStatus]]: "pending"[[PromiseValue]]: undefinedIl s'agit de l'état initial en attente
Et la résolution et le rejet peuvent contrôler le statut de la promesse

//resolve()
let p = new Promise((resolve, reject) => resolve("123")); //Promise {<resolved>: "123"}
//reject()
let p = new Promise((resolve, reject) => reject("123")); //reject()后是返回一个失败状态的Promise,不需要用catch来捕获不写catch会报错
p.catch(data => console.log(data));    
console.log(p);    //Promise {<rejected>: "123"}   123

Comme mentionné dans catch Il y en a un autre then
Pour le dire clairement : then(f1, f2) peut remplir deux paramètres de fonction. Un paramètre consiste à remplacer les paramètres de résolution dans f1 pour exécuter, et le deuxième paramètre consiste à remplacer les paramètres de rejet. dans f2. pour exécuter ; le deuxième paramètre peut être remplacé par catch, et il est plus puissant. catch peut capturer l'erreur dans then()

let p = new Promise((resolve, reject) => {
    
    let n = Math.ceil(Math.random() * 10);
    n > 5 ? resolve(n) : reject(n);
});
p.then(
    data => console.log(data),
    data => console.log(data),
)

Remplacer par catch et capturer l'erreur de then

let p = new Promise((resolve, reject) => {
    
    resolve("yes")
});
p.then(
    data => {console.log(data),console.log(a)}

).catch(data => console.log(data));
//yes
//ReferenceError: a is not defined
Parce que l'objet Promise est renvoyé après le traitement, ce qui facilite les appels en chaîne, il n'y a pas de retour dans then, alors comment peut-il y avoir un objet Promise ?

Même si la valeur de retour de then ou catch n'est pas explicitement spécifiée, ils enveloppent toujours automatiquement un objet de promesse avec un nouvel état rempli.

Lorsque nous l'imprimerons, nous trouverons :

Promise {<resolved>: undefined} Ensuite, nous pourrons afficher le retour d'un objet Promise et voir,

let p = new Promise((resolve, reject) => resolve("yes"));
p.then(data => Promise.resolve("第二个Promise")).then(data => console.log(data));   //第二个Promise
pouvons voir que

l'objet Promise renvoyé est p.then(data => Promise.resolve("第二个Promise")) et passez la valeur en paramètre dans le second puis exécutez Promise {<resolved>: "第二个Promise"}

Promise.resolve(value | promise | thenable) pour créer un objet Promise

Le premier paramètre est une valeur vide ou originale, et l'objet Promise est créé L'état est directement l'état résolu

Promise.resolve('f')
// 等价于
new Promise(resolve => resolve('f'))
Le deuxième

est à noter que l'objet avec la méthode then

let thenable = {
    then :(resolve, reject) => resolve("thenable")
}

let p = Promise.resolve(thenable);
console.log(p);
Promise l'état de l'objet est représenté par -> ;

Le troisième paramètre est l'objet Promise instancié,

let p1 = new Promise((resolve, reject) => false);
let p = Promise.resolve(p1);
console.log(p);
l'état p est cohérent avec l'état p1

Promise.reject(value) crée un objet Promise

La différence avec solve est que la valeur est directement passée en paramètre à

const thenable = {
  then(resolve, reject) {
    reject('出错了');
  }
};

Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
Le paramètre de la méthode catch n'est pas la chaîne "erreur" lancé par rejet, mais l'objet alors exploitable.

Promise.all

Enveloppez plusieurs instances Promise dans une nouvelle instance Promise ; const p = Promise.all([p1, p2, p3]);

(1) Ce n'est que lorsque les statuts de p1, p2 et p3 seront tous remplis que le statut de p sera rempli. À ce moment, les valeurs de retour de p1, p2 et p3 forment un tableau et sont transmises à la fonction de rappel de. p.

(2) Tant que l'un des p1, p2 et p3 est rejeté, le statut de p deviendra rejeté. À ce moment, la valeur de retour de la première instance rejetée sera transmise à la fonction de rappel. de p.

attendra que tous les objets soient exécutés avant de passer le tableau dans la fonction de rappel puis

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));
Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));    // ["p", "p2", "p2"]
let p = new Promise((resolve, reject) => resolve('p'));
let p1 = new Promise((resolve, reject) => reject('p2'));
let p2 = new Promise((resolve, reject) => resolve('p2'));
Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p2
Promise.race

La différence avec tout est : comme Tant que p1 Une instance parmi , p2 Et p3 change d'abord l'état, et l'état de p change en conséquence. La valeur de retour de l'instance Promise qui a changé en premier est transmise à la fonction de rappel de p.

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));
Promise.race([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p
L'ordre de la fonction de rappel et setTimeout de l'objet Promise

An event loop has one or more task queues. A task queue is an ordered list of tasks, which are algorithms that are responsible for such work as: events, parsing, callbacks, using a resource, reacting to DOM manipulation…Each event loop has a microtask queue. A microtask is a task that is originally to be queued on the microtask queue rather than a task queue.
  浏览器(或宿主环境) 遵循队列先进先出原则, 依次遍历macrotask queue中的每一个task, 不过每执行一个macrotask, 并不是立即就执行下一个, 而是执行一遍microtask queue中的任务, 然后切换GUI线程重新渲染或垃圾回收等.
  Event Loop (事件循环)拥有如下两种队列
  macrotask queue, 指的是宏任务队列, 包括rendering, script(页面脚本), 鼠标, 键盘, 网络请求等事件触发, setTimeout, setInterval, setImmediate(node)等等.
  microtask queue, 指的是微任务队列, 用于在浏览器重新渲染前执行, 包含Promise, process.nextTick(node), Object.observe, MutationObserver回调等.
  process.nextTick > promise.then > setTimeout ? setImmediate

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。

setTimeout(function() {
  console.log(4)
}, 0);
new Promise(function(resolve) {
  console.log(1);
  for (var i = 0; i < 10000; i++) {
    i == 9999 && resolve()
  }
  console.log(2);
}).then(function() {
  console.log(5)
});
console.log(3);  //1 2 3 5 4

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer