Mettre en œuvre la peomise à la main

Promesse / spécification A +

Dans le cadre de l'infrastructure JavaScript moderne, les promesses sont extrêmement importantes pour les développeurs frontaux.

C'est la base de la syntaxe async / await et de la forme standard de gestion asynchrone en JavaScript. De plus, les futures API Web, tant qu'elles sont asynchrones, apparaîtront sous forme de promesses.

Si vous ne comprenez pas les connaissances et le mécanisme de fonctionnement de Promises, vous ne pourrez peut-être pas terminer le travail quotidien de développement Web à l'avenir.

Par conséquent, Promises est devenu l'une des questions incontournables dans les entretiens frontaux. Sur Internet, vous pouvez également rechercher de nombreux articles techniques Promises. Il existe même des didacticiels payants frontaux pour vous apprendre à implémenter la spécification Promises / A + à partir de zéro en tant qu'argument de vente.

Pour les développeurs qui comprennent déjà Promises, la mise en œuvre de Promises / A + est une formation utile.

travaux préliminaires

Un standard ouvert pour des promesses JavaScript solides et interopérables

Comprendre la terminologie

1.1 “promise” is an object or function with a then method whose behavior conforms to this specification.
1.2 “thenable” is an object or function that defines a then method.
1.3 “value” is any legal JavaScript value (including undefined, a thenable, or a promise).
1.4 “exception” is a value that is thrown using the throw statement.
1.5 “reason” is a value that indicates why a promise was rejected.

La première partie de la spécification décrit la signification de plusieurs termes.

Une promesse est un objet ou une fonction qui contient la méthode then, qui est conforme au comportement spécifié par la spécification.

Thenable est une méthode qui contient alors et un objet ou une fonction.

value est une valeur JS légale.

L'exception est la valeur levée par l'instruction throw.

raison est une valeur indiquant pourquoi la promesse a été rejetée.

Statut de la promesse

A promise must be in one of three states: pending, fulfilled, or rejected.

2.1 When pending, a promise:
  2.1.1 may transition to either the fulfilled or rejected state.
2.2 When fulfilled, a promise:
  2.2.1 must not transition to any other state.
  2.2.2 must have a value, which must not change.
2.3 When rejected, a promise:
  2.3.1 must not transition to any other state.
  2.3.1 must have a reason, which must not change.

Une promesse a 3 états, qui sont en attente, remplis et rejetés.

Dans l'état en attente, la promesse peut être remplacée ou rejetée.

Dans l'état rempli, il ne peut pas être migré vers d'autres états et doit avoir une valeur immuable.

Dans l'état rejeté, il ne peut pas être transféré dans un autre état, et il doit y avoir une raison immuable.

Puis méthode

A promise must provide a then method to access its current or eventual value or reason.

A promise’s then method accepts two arguments:

promise.then(onFulfilled, onRejected)

Une promesse doit avoir une méthode then qui accepte les paramètres onFulfilled et onRejected.

Le paramètre de onFulfilled est la valeur et le paramètre de la fonction onRejected est la raison.

const PENDING = 'PENDING'
const RESOLVED = 'RESOLVED'
const REJECTED = 'REJECTED'

class Promise {
    
    
  constructor(executor) {
    
      // 执行器
    this.status = PENDING
    this.value = undefined
    this.reason = undefined

    let resolved = (value) => {
    
    
      if (this.status === PENDING) {
    
    
        this.value = value
        this.status = RESOLVED
      }
    }

    let rejected = (reason) => {
    
    
      if (this.status === PENDING) {
    
    
        this.reason = reason
        this.status = REJECTED
      }
    }

    try {
    
    
      executor(resolved, rejected)
    } catch (e) {
    
    
      rejected(e)
    }
  }
  then(onFulfilled, onRejected) {
    
    
    if (this.status === RESOLVED) {
    
    
      onFulfilled(this.value)
    }
    if (this.status === REJECTED) {
    
    
      onRejected(this.reason)
    }
  }
}

Gérer les situations asynchrones

class Promise {
    
    
  constructor {
    
    
    this.status = PENDING;
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    let resolve = (value) => {
    
    
      if (this.status === PENDING) {
    
    
        this.value = value;
        this.status = RESOLVED;
        this.onFulfilledCallbacks.forEach(fn => fn()); // 订阅
      }
    }

    let reject = (reason) => {
    
    
      if (this.status === PENDING) {
    
    
        this.reason = reason;
        this.status = REJECTED;
        this.onRejectedCallbacks.forEach(fn => fn());
      }
    }

    try {
    
    
      executor(resolve, reject);
    } catch (e) {
    
    
      reject(e);
    }
  }

  then(onFulfilled, onRejected) {
    
    
    let promise2 = new Promise((resolve, reject) => {
    
    
      if (this.status === RESOLVED) {
    
    
        // 根据x的值来判断promise2的状态
        setTimeout(() => {
    
    
          let x = onFulfilled(this.value);
          resolvePromise(promise2, x, resolve, reject);
        }, 0);
        
      }
      if (this.status === REJECTED) {
    
    
        onRejected(this.reason);
      }
      // 处理异步的情况
      if (this.status === PENDING) {
    
     //发布订阅模式
        this.onFulfilledCallbacks.push(() => {
    
    
          onFulfilled(this.value);
        })
        this.onRejectedCallbacks.push(() => {
    
    
          onRejected(this.reason);
        })
      }
    })
    return promise2;
  }
}

La procédure de résolution des promesses

[Échec du transfert de l'image du lien externe. Le site d'origine dispose peut-être d'un mécanisme de lien anti-sangsue. Il est recommandé d'enregistrer l'image et de la télécharger directement (img-pQiIDhqv-1614052331001) (… /… / .vuepress / public / img / promise .jpg)]

Dans la première étape, si le résultat est la promesse actuelle elle-même, une TypeError est levée.

Dans la deuxième étape, si result est une autre promesse, alors son état et ses états de résultat seront utilisés.

La troisième étape, si le résultat est un objet alors utilisable. Prenez d'abord la fonction then, puis appelez la fonction then et entrez à nouveau dans le processus The Promise Resolution Procedure.

const resolvePromise = (promise2, x, resolve, reject) => {
    
    
  if (promise2 === x) {
    
    
    return reject(new TypeError('Chaining cycle detected for promise #<Promise>]'));
  }
  if(typeof x === 'object' && x !== 'null' || typeof x === 'function') {
    
    
    try {
    
    
      let then = x.then;
      if (typeof then === 'function') {
    
    
        then.call(x, y => {
    
    
          resolve(y);
        }, r => {
    
    
          reject(r);
        })
      }
    } catch (e) {
    
    
      reject(e);
    }
    let then = x.then;
  } else {
    
    
    resolve(x);
  }
}

Pour résumer

Être capable de mettre en œuvre les promesses à la main n'est pas utile pour maîtriser les promesses. La spécification Promise / A + se concentre sur la façon de mettre en œuvre. Pas comment utiliser.

Si vous voulez maîtriser les promesses, vous devez réfléchir et vous entraîner davantage aux différents scénarios asynchrones de développement quotidien.

Je suppose que tu aimes

Origine blog.csdn.net/Beth__hui/article/details/113979969
conseillé
Classement