Ce n'est pas un problème du monde réel, j'essaie simplement de comprendre comment les promesses sont créées.
J'ai besoin de comprendre comment faire une promesse pour une fonction qui ne renvoie rien, comme setTimeout.
Supposons que j'ai:
function async(callback){
setTimeout(function(){
callback();
}, 5000);
}
async(function(){
console.log('async called back');
});
Comment créer une promesse qui async
peut revenir une fois que le setTimeout
est prêt callback()
?
Je supposais que l'envelopper m'emmènerait quelque part:
function setTimeoutReturnPromise(){
function promise(){}
promise.prototype.then = function() {
console.log('timed out');
};
setTimeout(function(){
return ???
},2000);
return promise;
}
Mais je ne peux pas penser au-delà de ça.
javascript
settimeout
promise
réflexe de retard
la source
la source
async function async(){...}
Réponses:
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
Promise
constructeur (l'Promise
exécuteur ) qui reçoit les fonctions de résolution / rejet de la promesse comme arguments.Premièrement, puisque
async
maintenant a une signification en JavaScript (même si ce n'est qu'un mot-clé dans certains contextes), je vais utiliserlater
comme 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:
Notez que cela suppose une version de
setTimeout
qui est conforme à la définition des navigateurs oùsetTimeout
ne 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
setTimeout
aprè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):Si vous utilisez les fonctions fléchées ES2015 +, cela peut être plus concis:
ou même
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
cancel
méthode et un accesseur pour la promesse, et rejeter la promesse en cas d'annulation:Exemple en direct:
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
later
aurait tendance à ressembler à quelque chose comme ceci:Dans un commentaire sur la question, j'ai demandé:
et tu as dit
Pour aider à cette compréhension, voici un exemple très très basique , qui n'est pas conforme à distance Promises-A: Live Copy
la source
Ce n'est pas une réponse à la question initiale. Mais, comme une question originale n'est pas un problème réel, elle ne devrait pas être un problème. J'ai essayé d'expliquer à un ami ce que sont les promesses en JavaScript et la différence entre promesse et rappel.
Le code ci-dessous sert d'explication:
JsFiddle
la source