Heim  >  Artikel  >  Web-Frontend  >  Was ist Versprechen in ECMAScript6? Was ist der Nutzen? (mit Beispielen)

Was ist Versprechen in ECMAScript6? Was ist der Nutzen? (mit Beispielen)

不言
不言nach vorne
2018-10-24 11:44:472004Durchsuche

Der Inhalt dieses Artikels befasst sich mit der Frage: Was ist Promise in ECMAScript6? Was ist der Nutzen? (Mit Beispielen) hat es einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen.

Ich bin gerade mit dem Lernen fertig und habe einen ungefähren Eindruck. Organisieren und notieren Sie es zum späteren Studium und zur Ergänzung, um Ihr Verständnis zu vertiefen.

Was ist Promise?

Promise ist ein Konstruktor, der Promise-Objekte durch neue generieren kann.

Was nützt Promise?

Mein aktuelles Gefühl ist: Es ist bequemer, asynchrone Prozesse zu betreiben, der Prozess der Ereignissteuerung ist klarer und intuitiver und es kann in Ketten aufgerufen werden

Promise-Funktionen

Auszug aus ES6 Getting Started

Promise-Objekte haben die folgenden zwei Funktionen.
(1) Der Zustand des Objekts wird von der Außenwelt nicht beeinflusst. Das Promise-Objekt stellt einen asynchronen Vorgang dar und hat drei Zustände: ausstehend (in Bearbeitung), erfüllt (erfolgreich) und abgelehnt (fehlgeschlagen). Nur das Ergebnis der asynchronen Operation kann den aktuellen Status bestimmen, und keine andere Operation kann diesen Status ändern. Dies ist auch der Ursprung des Namens Promise. Seine englische Bedeutung ist „Engagement“, was bedeutet, dass er nicht auf andere Weise geändert werden kann.
(2) Sobald sich der Status ändert, ändert er sich nicht mehr und dieses Ergebnis kann jederzeit abgerufen werden. Es gibt nur zwei Möglichkeiten, den Status eines Promise-Objekts zu ändern: von „Ausstehend“ zu „Erfüllt“ und von „Ausstehend“ zu „Abgelehnt“. Solange diese beiden Situationen auftreten, wird sich der Zustand verfestigen, sich nicht mehr ändern und dieses Ergebnis beibehalten gelöst. Wenn die Änderung bereits erfolgt ist und Sie dem Promise-Objekt eine Rückruffunktion hinzufügen, erhalten Sie das Ergebnis sofort. Das ist etwas völlig anderes als ein Ereignis. Das Besondere an einem Ereignis ist, dass man kein Ergebnis erhält, wenn man es verpasst und noch einmal zuhört.

Verstehen Sie es anhand einiger einfacher Beispiele

Konstruieren Sie ein einfaches Promise-Objekt durch new

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

Die beiden übergebenen Parameter werden verwendet, um den Status des Promise-Objekts We zu steuern Drucken Sie p, um den Status anzuzeigen:
Promise {__proto__: Promise[[PromiseStatus]]: "pending"[[PromiseValue]]: undefinedDies ist der Anfangsstatus „Ausstehend“
Und „Auflösen“ und „Ablehnen“ können den Status von „Promise“ steuern

//resolve()
let p = new Promise((resolve, reject) => resolve("123")); //Promise {<resolved>: "123"}
rrree

Wenn Sie „catch“ erwähnen, gibt es noch einen weiteren Status
Um es ganz klar auszudrücken: then(f1, f2) kann zwei Funktionsparameter ausfüllen, um den Parameter in „resolve“ durch f1 zu ersetzen, um ihn auszuführen, und der zweite Parameter besteht darin, den Parameter in „reject“ durch „f2“ zu ersetzen zweiter Parameter Sie können stattdessen Catch verwenden, und es ist leistungsfähiger. Catch kann den Fehler in then()

//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

Verwenden Sie stattdessen „catch“ und erfassen Sie den Fehler von 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),
)

aufgrund des Ergebnisses Nach der Verarbeitung wird immer noch ein Promise-Objekt zurückgegeben, was Kettenaufrufe erleichtert. Es gibt dann keine Rückgabe. Wie kann es also ein Promise-Objekt geben?

Auch wenn der Rückgabewert von then oder Catch nicht explizit angegeben ist, umschließen sie ein Promise-Objekt immer automatisch mit einem neuen erfüllten Status.

Wenn wir es drucken, finden wir: Promise {<resolved>: undefined}
Dann können wir die Rückgabe eines Promise-Objekts anzeigen und sehen,

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

kann sehen, dass p.then(data => Promise.resolve("第二个Promise")) das zurückgegebene Promise-Objekt und der Wert Der Wert wird dann als Parameter an den zweiten übergeben, um Promise {<resolved>: "第二个Promise"}

Promise.resolve(value | Promise | thenable) auszuführen, um ein Promise-Objekt zu erstellen

Der erste Parameter ist leer oder der Originalwert , und der Status des Promise-Objekts nach der Erstellung ist direkt Für den aufgelösten Zustand

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

Es ist erwähnenswert, dass das Objekt mit der then-Methode

Promise.resolve('f')
// 等价于
new Promise(resolve => resolve('f'))
Promise-Objekt Der Status wird durch -> dargestellt. Der dritte Parameter ist das instanziierte Promise-Objekt.

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

let p = Promise.resolve(thenable);
console.log(p);

p-Status stimmt mit p1-Status überein. „reject(value)“ erstellt ein Promise-Objekt . Der Unterschied zu „resolve“ besteht darin, dass der Wert direkt als Parameter an die

let p1 = new Promise((resolve, reject) => false);
let p = Promise.resolve(p1);
console.log(p);
catch-Methode übergeben wird. Der Parameter der Catch-Methode ist nicht die Zeichenfolge „error“. geworfen durch Reject, aber das dann mögliche Objekt.


Promise.all

Mehrere Promise-Instanzen in eine neue Promise-Instanz einschließen; const p = Promise.all([p1, p2, p3]);

(1) Erst wenn der Status von p1, p2 und p3 erfüllt ist, wird der Status von p erfüllt. Zu diesem Zeitpunkt bilden die Rückgabewerte von p1, p2 und p3 ein Array und werden an die Rückruffunktion von übergeben P.

(2) Solange p1, p2 und p3 abgelehnt werden, wird der Status von p abgelehnt. Zu diesem Zeitpunkt wird der Rückgabewert der ersten abgelehnten Instanz an die Rückruffunktion übergeben von p .

wartet darauf, dass alle Objekte insgesamt ausgeführt werden, bevor das Array an die Rückruffunktion übergeben wird. Dann

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

Promise.reject(thenable)
.catch(e => {
  console.log(e === thenable)
})
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"]

Promise.race

Der Unterschied zu allen ist: solange p1, p2 , p3 Eine der Instanzen ändert zuerst ihren Zustand und der Zustand von p ändert sich entsprechend. Der Rückgabewert der Promise-Instanz, die sich zuerst geändert hat, wird an die Rückruffunktion von p übergeben.

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
Die Reihenfolge der Rückruffunktion und setTimeout des Promise-Objekts

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

Das obige ist der detaillierte Inhalt vonWas ist Versprechen in ECMAScript6? Was ist der Nutzen? (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen