Mise à jour (2017)
Ici en 2017, les promesses sont intégrées à JavaScript, elles ont été ajoutées par la spécification ES2015 (les polyfills sont disponibles pour les environnements obsolètes comme IE8-IE11). La syntaxe avec laquelle ils sont allés utilise un rappel que vous passez au Promiseconstructeur (l' Promise exécuteur ) qui reçoit les fonctions de résolution / rejet de la promesse comme arguments.
Premièrement, puisque asyncmaintenant a une signification en JavaScript (même si ce n'est qu'un mot-clé dans certains contextes), je vais utiliser latercomme nom de la fonction pour éviter toute confusion.
Délai de base
En utilisant des promesses natives (ou un polyfill fidèle), cela ressemblerait à ceci:
function later(delay) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay);
    });
}
Notez que cela suppose une version de setTimeoutqui est conforme à la définition des navigateurs où setTimeoutne transmet aucun argument au rappel à moins que vous ne les donniez après l'intervalle (cela peut ne pas être vrai dans les environnements sans navigateur, et ce n'était pas le cas auparavant vrai sur Firefox, mais c'est maintenant; c'est vrai sur Chrome et même de retour sur IE8).
Délai de base avec valeur
Si vous voulez que votre fonction passe éventuellement une valeur de résolution, sur n'importe quel navigateur vaguement moderne qui vous permet de donner des arguments supplémentaires setTimeoutaprès le délai, puis de les transmettre au rappel lorsqu'il est appelé, vous pouvez le faire (Firefox et Chrome actuels; IE11 + , probablement Edge; pas IE8 ou IE9, aucune idée de IE10):
function later(delay, value) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delay, value); // Note the order, `delay` before `value`
        /* Or for outdated browsers that don't support doing that:
        setTimeout(function() {
            resolve(value);
        }, delay);
        Or alternately:
        setTimeout(resolve.bind(null, value), delay);
        */
    });
}
Si vous utilisez les fonctions fléchées ES2015 +, cela peut être plus concis:
function later(delay, value) {
    return new Promise(resolve => setTimeout(resolve, delay, value));
}
ou même
const later = (delay, value) =>
    new Promise(resolve => setTimeout(resolve, delay, value));
Retard annulable avec valeur
Si vous souhaitez rendre possible l'annulation du délai d'expiration, vous ne pouvez pas simplement renvoyer une promesse later, car les promesses ne peuvent pas être annulées.
Mais nous pouvons facilement renvoyer un objet avec une cancelméthode et un accesseur pour la promesse, et rejeter la promesse en cas d'annulation:
const later = (delay, value) => {
    let timer = 0;
    let reject = null;
    const promise = new Promise((resolve, _reject) => {
        reject = _reject;
        timer = setTimeout(resolve, delay, value);
    });
    return {
        get promise() { return promise; },
        cancel() {
            if (timer) {
                clearTimeout(timer);
                timer = 0;
                reject();
                reject = null;
            }
        }
    };
};
Exemple en direct:
const later = (delay, value) => {
    let timer = 0;
    let reject = null;
    const promise = new Promise((resolve, _reject) => {
        reject = _reject;
        timer = setTimeout(resolve, delay, value);
    });
    return {
        get promise() { return promise; },
        cancel() {
            if (timer) {
                clearTimeout(timer);
                timer = 0;
                reject();
                reject = null;
            }
        }
    };
};
const l1 = later(100, "l1");
l1.promise
  .then(msg => { console.log(msg); })
  .catch(() => { console.log("l1 cancelled"); });
const l2 = later(200, "l2");
l2.promise
  .then(msg => { console.log(msg); })
  .catch(() => { console.log("l2 cancelled"); });
setTimeout(() => {
  l2.cancel();
}, 150);
 
 
Réponse originale de 2014
Habituellement, vous aurez une bibliothèque de promesses (celle que vous écrivez vous-même, ou l'une des nombreuses). Cette bibliothèque aura généralement un objet que vous pourrez créer et «résoudre» plus tard, et cet objet aura une «promesse» que vous pourrez en tirer.
Alors lateraurait tendance à ressembler à quelque chose comme ceci:
function later() {
    var p = new PromiseThingy();
    setTimeout(function() {
        p.resolve();
    }, 2000);
    return p.promise(); // Note we're not returning `p` directly
}
Dans un commentaire sur la question, j'ai demandé:
  Essayez-vous de créer votre propre bibliothèque de promesses?
et tu as dit
  Je ne l'étais pas mais je suppose que c'est en fait ce que j'essayais de comprendre. Voilà comment une bibliothèque le ferait
Pour aider à cette compréhension, voici un exemple très très basique , qui n'est pas conforme à distance Promises-A: Live Copy
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Very basic promises</title>
</head>
<body>
  <script>
    (function() {
      // ==== Very basic promise implementation, not remotely Promises-A compliant, just a very basic example
      var PromiseThingy = (function() {
        // Internal - trigger a callback
        function triggerCallback(callback, promise) {
          try {
            callback(promise.resolvedValue);
          }
          catch (e) {
          }
        }
        // The internal promise constructor, we don't share this
        function Promise() {
          this.callbacks = [];
        }
        // Register a 'then' callback
        Promise.prototype.then = function(callback) {
          var thispromise = this;
          if (!this.resolved) {
            // Not resolved yet, remember the callback
            this.callbacks.push(callback);
          }
          else {
            // Resolved; trigger callback right away, but always async
            setTimeout(function() {
              triggerCallback(callback, thispromise);
            }, 0);
          }
          return this;
        };
        // Our public constructor for PromiseThingys
        function PromiseThingy() {
          this.p = new Promise();
        }
        // Resolve our underlying promise
        PromiseThingy.prototype.resolve = function(value) {
          var n;
          if (!this.p.resolved) {
            this.p.resolved = true;
            this.p.resolvedValue = value;
            for (n = 0; n < this.p.callbacks.length; ++n) {
              triggerCallback(this.p.callbacks[n], this.p);
            }
          }
        };
        // Get our underlying promise
        PromiseThingy.prototype.promise = function() {
          return this.p;
        };
        // Export public
        return PromiseThingy;
      })();
      // ==== Using it
      function later() {
        var p = new PromiseThingy();
        setTimeout(function() {
          p.resolve();
        }, 2000);
        return p.promise(); // Note we're not returning `p` directly
      }
      display("Start " + Date.now());
      later().then(function() {
        display("Done1 " + Date.now());
      }).then(function() {
        display("Done2 " + Date.now());
      });
      function display(msg) {
        var p = document.createElement('p');
        p.innerHTML = String(msg);
        document.body.appendChild(p);
      }
    })();
  </script>
</body>
</html>