Heim > Web-Frontend > js-Tutorial > Hauptteil

Implementieren Sie die Promise-Bibliothek mit Js

php中世界最好的语言
Freigeben: 2018-06-07 13:46:54
Original
1913 Leute haben es durchsucht

Dieses Mal werde ich Ihnen die Verwendung von JS zur Implementierung der Promise-Bibliothek vorstellen. Was sind die Vorsichtsmaßnahmen für die Verwendung von JS zur Implementierung der Promise-Bibliothek?

Vorwort

ECMAScript ist der internationale Standard für die JavaScript-Sprache, und JavaScript ist die Implementierung von ECMAScript. Das Ziel von ES6 besteht darin, die Verwendung der JavaScript-Sprache zum Schreiben großer und komplexer Anwendungen zu ermöglichen und eine Entwicklungssprache auf Unternehmensebene zu werden.

Konzept

ES6 stellt nativ Promise-Objekte bereit.

Das sogenannte Promise ist ein Objekt, das zur Übermittlung von Nachrichten für asynchrone Vorgänge verwendet wird. Es stellt ein Ereignis dar (normalerweise eine asynchrone Operation), dessen Ergebnis erst in der Zukunft bekannt ist, und dieses Ereignis stellt eine einheitliche API für die weitere Verarbeitung bereit.

Drei Fragen zum Nachdenken

Als ich zum ersten Mal mit dem Schreiben des Frontends begann, habe ich häufig Rückrufe verwendet, um asynchrone Anfragen zu bearbeiten einfach und bequem. Später, als ich schrieb, verzichtete ich auf Rückrufe und begann, Versprechen zu verwenden, um asynchrone Probleme zu lösen. Versprechen ist in der Tat schöner zu schreiben, aber aufgrund des Mangels an tiefem Verständnis seiner internen Struktur ist es nicht immer einfach, Versprechen zu verwenden, wenn man auf komplexe Situationen stößt, und das Debuggen dauert lange.

In diesem Artikel werde ich Sie also dazu bringen, bei Null anzufangen und ein grundsätzlich brauchbares Versprechen von Hand zu schreiben. Nachdem ich es aufgeschrieben habe, werden Sie ein klares Verständnis davon haben, was ein Versprechen ist und welche interne Struktur es hat, und Sie werden in der Lage sein, Versprechen in Zukunft in komplexen Szenarien einzusetzen.

Um außerdem zu testen, ob jeder Versprechen wirklich beherrscht, werde ich am Ende des Artikels ein paar Übungsfragen zu Versprechen stellen. Es wird gesagt, dass es sich dabei um Übungen handelt, in Wirklichkeit handelt es sich jedoch um Abstraktionen realer Szenarien, denen jeder in seinen Projekten begegnen wird. Wenn man sie kompetent beherrscht, kann das jedem helfen, seine Front-End-Fähigkeiten zu verbessern.

Die drei Übungsfragen werden im Voraus gestellt. Sie können den folgenden Inhalt ignorieren und sich grob vorstellen, wie Sie sie in Ihrem Kopf lösen werden:

  • Versprechens-Array-Kettenaufruf?

  • Wie kontrolliere ich die Parallelität mit Versprechen?

  • Wie führt man asynchrones Caching mit Versprechen durch?

Die oben genannten drei Denkfragen haben eigentlich wenig damit zu tun, ob Sie Versprechen verwenden oder nicht, aber wenn Sie Versprechen nicht tiefgreifend verstehen, ist es wirklich nicht so einfach, diese drei zu lösen Probleme.

Was ist Versprechen?

Zurück zum Text: Was ist Versprechen? Um es ganz klar auszudrücken: Ein Versprechen ist ein Container, der das Ergebnis eines Ereignisses (normalerweise einer asynchronen Operation) speichert, das in der Zukunft enden wird.

Zunächst legt ES6 fest, dass das Promise-Objekt ein Konstruktor ist, der zum Generieren von Promise-Instanzen verwendet wird. Dann akzeptiert dieser Konstruktor eine Funktion (Executor) als Parameter, und die beiden Parameter der Funktion sind Auflösung und Ablehnung. Nachdem die Promise-Instanz generiert wurde, können Sie schließlich die Methode then verwenden, um die Rückruffunktionen (onFulfilled und onRejected) für den aufgelösten Status bzw. den abgelehnten Status anzugeben.

Die spezifische Verwendungsmethode wird im Code wie folgt ausgedrückt:

const promise = new Promise(function(resolve, reject) {
 // ... some code
 if (/* 异步操作成功 */){
 resolve(value);
 } else {
 reject(error);
 }
});
promise.then(function(value) {
 // success
}, function(error) {
 // failure
});
Nach dem Login kopieren

Nachdem wir dies verstanden haben, können wir mutig mit der Konstruktion unseres eigenen Versprechens beginnen und ihm einen Namen geben: CutePromise

Implementieren Sie ein Versprechen: CutePromise

Wir verwenden ES6-Klassen direkt, um unser CutePromise zu erstellen. Wenn Sie mit der ES6-Syntax nicht vertraut sind, können Sie meine anderen beiden Artikel lesen Einführung in die Kernsyntax von ES6, bevor wir zurückkommen. Beherrschen Sie den Kerninhalt von ES6/ES2015 in 30 Minuten (Teil 1), Beherrschen Sie den Kerninhalt von ES6/ES2015 in 30 Minuten (Teil 2)

class CutePromise {
 // executor是我们实例化CutePromise时传入的参数函数,它接受两个参数,分别是resolve和reject。
 // resolve和reject我们将会定义在constructor当中,供executor在执行的时候调用
 constructor(executor) {
 const resolve = () => {}
 const reject = () => {}
 executor(resolve, reject)
 }
 // 为实例提供一个then的方法,接收两个参数函数,
 // 第一个参数函数必传,它会在promise已成功(fulfilled)以后被调用
 // 第二个参数非必传,它会在promise已失败(rejected)以后被调用
 then(onFulfilled, onRejected) {}
}
Nach dem Login kopieren

Nachdem wir unser CutePromise erstellt haben, wollen wir einen wichtigen Punkt herausfinden: der Zustand des Promise-Objekts.

Das Promise-Objekt steuert asynchrone Vorgänge über seinen eigenen Status. Eine Promise-Instanz hat drei Zustände:

  • Asynchroner Vorgang ausstehend (pending)

  • Asynchroner Vorgang erfolgreich (erfüllt)

  • Asynchroner Vorgang fehlgeschlagen (abgelehnt)

Von den oben genannten drei Zuständen werden erfüllt und abgelehnt gemeinsam als gelöst (abgeschlossen) bezeichnet. Es gibt nur zwei Möglichkeiten, den Status zu ändern: Der erste ist „ausstehend=>erfüllt“ und der andere ist „ausstehend=>abgelehnt“. Sobald der Status geändert wurde, kann er nicht geändert werden.

Jetzt fügen wir den Status zu CutePromise hinzu. Der ungefähre Vorgang ist:

首先,实例化初始过程中,我们先将状态设为PENDING,然后当executor执行resolve的时候,将状态更改为FULFILLED,当executor执行reject的时候将状态更改为REJECTED。同时更新实例的value。

constructor(executor) {
 ...
 this.state = 'PENDING';
 ...
 const resolve = (result) => {
  this.state = 'FULFILLED';
  this.value = result;
 }
 const reject = (error) => {
  this.state = 'REJECTED';
  this.value = error;
 }
 ...
}
Nach dem Login kopieren

再来看下我们的then函数。then函数的两个参数,onFulfilled表示当promise异步操作成功时调用的函数,onRejected表示当promise异步操作失败时调用的函数。假如我们调用then的时候,promise已经执行完成了(当任务是个同步任务时),我们可以直接根据实例的状态来执行相应的函数。假如promise的状态还是PENDING, 那我们就将onFulfilled和onRejected直接存储到chained这个变量当中,等promise执行完再调用。

constructor(executor) {
 ...
 this.state = 'PENDING';
 
 // chained用来储存promise执行完成以后,需要被依次调用的一系列函数
 this.chained = [];
 const resolve = (result) => {
  this.state = 'FULFILLED';
  this.value = result;
  
  // promise已经执行成功了,可以依次调用.then()函数里的onFulfilled函数了
  for (const { onFulfilled } of this.chained) {
   onFulfilled(res);
  }
 }
 ...
}
then(onFulfilled, onRejected) {
 if (this.state === 'FULFILLED') {
 onFulfilled(this.value);
 } else if (this.state === 'REJECTED') {
 onRejected(this.value);
 } else {
 this.$chained.push({ onFulfilled, onRejected });
 }
}
Nach dem Login kopieren

这样我们就完成了一个CutePromise的创建,下面是完整代码,大家可以复制代码到控制台测试一下:

class CutePromise {
 constructor(executor) {
 if (typeof executor !== 'function') {
  throw new Error('Executor must be a function');
 }
 this.state = 'PENDING';
 this.chained = [];
 const resolve = res => {
  if (this.state !== 'PENDING') {
  return;
  }
  this.state = 'FULFILLED';
  this.internalValue = res;
  for (const { onFulfilled } of this.chained) {
  onFulfilled(res);
  }
 };
 const reject = err => {
  if (this.state !== 'PENDING') {
  return;
  }
  this.state = 'REJECTED';
  this.internalValue = err;
  for (const { onRejected } of this.chained) {
  onRejected(err);
  }
 };
 try {
  executor(resolve, reject);
 } catch (err) {
  reject(err);
 }
 }
 
 then(onFulfilled, onRejected) {
 if (this.state === 'FULFILLED') {
  onFulfilled(this.internalValue);
 } else if (this.$state === 'REJECTED') {
  onRejected(this.internalValue);
 } else {
  this.chained.push({ onFulfilled, onRejected });
 }
 }
}
Nach dem Login kopieren

提供一下测试代码:

let p = new CutePromise(resolve => {
 setTimeout(() => resolve('Hello'), 100);
});
p.then(res => console.log(res));
p = new CutePromise((resolve, reject) => {
 setTimeout(() => reject(new Error('woops')), 100);
});
p.then(() => {}, err => console.log('Async error:', err.stack));
p = new CutePromise(() => { throw new Error('woops'); });
p.then(() => {}, err => console.log('Sync error:', err.stack));
Nach dem Login kopieren

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

JS实现输入框内灰色文字提示

路径中#号怎样除去

Das obige ist der detaillierte Inhalt vonImplementieren Sie die Promise-Bibliothek mit Js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage