Maison >interface Web >js tutoriel >L'utilisation de Promise en JavaScript
Promise est une fonction dans ES6 qui standardise la façon de gérer les fonctions de rappel pour les tâches asynchrones. Sa fonction est similaire à celle différée de jQuery. En termes simples, différentes fonctions de rappel sont appelées via différents états de l'objet promis. Actuellement, IE8 et versions antérieures ne sont pas pris en charge, mais d'autres navigateurs le sont.
L'état de l'objet de promesse ne changera pas une fois qu'il sera converti de En attente à Résolu ou Rejeté.
Étapes d'utilisation :
var promise = new Promise(function(resolve, reject) { // 异步任务,通过调用resolve(value) 或 reject(error),以改变promise对象的状态;改变状态的方法只能在此调用。 //promise状态改变后,会调用对应的回调方法 }); promise.then(function(value){//resolve时的回调函数,参数由异步的函数传进来}) .catch(function(error){//发生异常时或明确reject()时的回调函数})
Utilisation spécifique :
function getURL(URL) { //因为promise创建时即执行,所以用工厂函数封装promise对象 return new Promise(function (resolve, reject) { var req = new XMLHttpRequest(); req.open('GET', URL, true); req.onload = function () { if (req.status === 200) { resolve(req.responseText); } else { reject(new Error(req.statusText)); } }; req.onerror = function () { reject(new Error(req.statusText)); }; req.send(); }); } // 运行示例 var URL = "http://httpbin.org/get"; getURL(URL).then(function onFulfilled(value){ console.log(value); }).catch(function onRejected(error){ console.error(error); })
Le rappel de Promise est uniquement asynchrone, même le rappel d'une tâche synchrone est exécuté de manière asynchrone.
var promise = new Promise(function (resolve){ console.log("inner promise"); // 执行1:同步任务先执行 resolve(‘callBack'); }); promise.then(function(value){ console.log(value); // 执行3:虽然注册时状态为resolved,但回调仍是异步的; }); console.log("outer promise"); // 执行2:同步代码先执行
Chaîne de méthodes promises
Les rappels enregistrés par la méthode then seront appelés dans l'ordre et les paramètres sont transmis entre chaque méthode then via la valeur de retour. Cependant, les exceptions dans les rappels entraîneront l'omission des rappels then, l'appel direct des rappels catch, puis l'appel des rappels then restants. Dans then(onFulfilled, onRejected), l'exception onFulfilled ne sera pas interceptée par son propre onRejected, donc catch est utilisé en premier.
promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask);
taskA lève une exception, la tâcheB est ignorée et finalTask sera toujours appelé, car Le statut de l'objet de promesse renvoyé par catch est résolu.
3 types de valeurs peuvent être renvoyés dans la méthode then
1. Renvoie un autre objet de promesse La méthode then suivante sélectionne la fonction de rappel onFullfilled/onRejected à exécuter en fonction de son statut. Les paramètres sont toujours déterminés par la résolution de la nouvelle promesse. /reject method delivery
2. Renvoie une valeur synchrone. La méthode next then utilise l'état de l'objet de promesse actuel et sera exécutée immédiatement sans attendre. pour que la tâche asynchrone se termine ; le paramètre réel est la valeur de retour du précédent alors ; s'il ne renvoie pas, il renvoie undéfini par défaut
3. xxx');
alors non seulement enregistre une fonction de rappel, mais également La valeur de retour de la fonction de rappel est transformée, créant et renvoyant un nouvel objet de promesse. En fait, Promise n’opère pas sur le même objet de promesse dans la chaîne de méthodes.
var aPromise = new Promise(function (resolve) { resolve(100); }); var thenPromise = aPromise.then(function (value) { console.log(value); }); var catchPromise = thenPromise.catch(function (error) { console.error(error); }); console.log(aPromise !== thenPromise); // => true console.log(thenPromise !== catchPromise);// => true
Méthode statique Promise.all(), effectue plusieurs tâches asynchrones en même temps. Le traitement ultérieur ne se poursuivra pas tant que tous les objets de promesse reçus ne seront pas FulFilled ou Rejected.
Promise.all([promiseA, promiseB]).then(function(results){//results是个数组,元素值和前面promises对象对应}); // 由promise对象组成的数组会同时执行,而不是一个一个顺序执行,开始时间基本相同。 function timerPromisefy(delay) { console.log('开始时间:”'+Date.now()) return new Promise(function (resolve) { setTimeout(function () { resolve(delay); }, delay); }); } var startDate = Date.now(); Promise.all([ timerPromisefy(100), //promise用工厂形式包装一下 timerPromisefy(200), timerPromisefy(300), timerPromisefy(400) ]).then(function (values) { console.log(values); // [100,200,300,400] });
ne sont pas exécutés en même temps, mais sont exécutés l'un après l'autre
//promise factories返回promise对象,只有当前异步任务结束时才执行下一个then function sequentialize(promiseFactories) { var chain = Promise.resolve(); promiseFactories.forEach(function (promiseFactory) { chain = chain.then(promiseFactory); }); return chain; }
Promise.race() est similaire à all(), mais race() uniquement. a besoin d'un objet de promesse pour entrer. S'il est dans l'état FulFilled ou Rejected, la fonction de rappel correspondante sera exécutée. Cependant, une fois que le premier objet de promesse est rempli, cela n’affecte pas la poursuite de l’exécution des autres objets de promesse.
//沿用Promise.all()的例子 Promise.race([ timerPromisefy(1), timerPromisefy(32), timerPromisefy(64), timerPromisefy(128) ]).then(function (value) { console.log(values); // [1] });
La merveilleuse utilisation de Promise.race() comme minuterie
Promise.race([ new Promise(function (resolve, reject) { setTimeout(reject, 5000); // timeout after 5 secs }), doSomethingThatMayTakeAwhile() ]);
Changer le statut de la promesse dans then
Parce qu'il n'y a qu'un seul paramètre de valeur dans then callback, non La méthode de changement d'état (ne peut être utilisée que dans la tâche asynchrone du constructeur). Si vous souhaitez modifier l'état de l'objet de promesse passé au suivant, vous pouvez uniquement créer un nouvel objet Promise et déterminer. s'il faut changer l'état dans la tâche asynchrone. Enfin, le retour est passé au prochain then/catch.
var promise = Promise.resolve(‘xxx');//创建promise对象的简介方法 promise.then(function (value) { var pms=new Promise(function(resolve,reject){ setTimeout(function () { // 在此可以判断是否改变状态reject/resolve Reject(‘args'); }, 1000); }) return pms; //该promise对象可以具有新状态,下一个then/catch需要等异步结束才会执行回调;如果返回普通值/undefined,之后的then/catch会立即执行 }).catch(function (error) { // 被reject时调用 console.log(error) });
Obtenez les résultats de deux promesses
//方法1:通过在外层的变量传递 var user; getUserByName('nolan').then(function (result) { user = result; return getUserAccountById(user.id); }).then(function (userAccount) { //可以访问user和userAccount }); //方法2:后一个then方法提到前一个回调中 getUserByName('nolan').then(function (user) { return getUserAccountById(user.id).then(function (userAccount) { //可以访问user和userAccount }); });
Faites attention à la structure globale lorsque vous utilisez des promesses
Supposons que doSomething() et doSomethingElse() renvoient objets promis
Manières courantes :
doSomething().then(doSomethingElse).then(finalHandler); doSomething |-----------------| doSomethingElse(resultOfDoSomething) //返回新promise,下一个then要收到新状态才执行 |------------------| finalHandler(resultOfDoSomethingElse) |---------------------|
Solutions de contournement courantes :
doSomething().then(function () { return doSomethingElse();}).then(finalHandler); doSomething |-----------------| doSomethingElse(undefined) //then外层函数的arguments[0]== resultOfDoSomething |------------------| finalHandler(resultOfDoSomethingElse) |------------------|
Manière incorrecte 1 :
doSomething().then(function () { doSomethingElse();}).then(finalHandler); doSomething |-----------------| doSomethingElse(undefined) //虽然doSomethingElse会返回promise对象,但最外层的回调函数是return undefined,所以下一个then方法无需等待新promise的状态,会马上执行回调。 |------------------| finalHandler(undefined) |------------------|
Manière incorrecte 2 :
doSomething().then(doSomethingElse()).then(finalHandler); doSomething |-----------------| doSomethingElse(undefined) //回调函数在注册时就直接被调用 |----------| finalHandler(resultOfDoSomething) |------------------|
Pour plus d'articles liés à l'utilisation de Promise en JavaScript, veuillez faire attention au site Web PHP chinois !