Maison > interface Web > js tutoriel > le corps du texte

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

青灯夜游
Libérer: 2021-07-09 10:09:19
avant
1718 Les gens l'ont consulté

Cet article vous présentera NodejsPromise dans la programmation asynchrone et vous présentera en quoi Promise est meilleure que le rappel.

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

【Apprentissage recommandé : "Tutoriel Nodejs"】

Qu'est-ce que Promise

Promise est une solution de programmation asynchrone !

  • La boucle d'événements actuelle ne peut pas obtenir le résultat, mais la boucle d'événements futurs vous donnera le résultat
  • est une machine à états
    • pengding
    • résolu
    • reejectd

À quoi ressemble le flux d'état à partir du code ?

En attente de résolution du test de flux

(function () {
  const res = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, 500);
  });
  console.log("500ms", res);

  setTimeout(() => {
    console.log("800ms", res);
  }, 800);
})();
Copier après la connexion

Imprimer le contenu suivant

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

Le résultat est conforme à nos attentes

  • Nous ne pouvons pas obtenir le résultat de la promesse immédiatement, à ce moment, la promesse est dans l'état en attente promise的结果,此时promise处于pending状态
  • 必须等待一段时间过后才能获取promise的结果,此时promise处于fulfilled状态

pending 到 reject 的流转测试

(function () {
  const res = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error("error"));
    }, 500);
  });
  console.log("500ms", res);

  setTimeout(() => {
    console.log("800ms", res);
  }, 800);
})();
Copier après la connexion

打印出如下内容

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

结果是符合我们的预期的

  • 我们无法立即获取promise的结果,此时promise处于pending状态
  • 必须等待一段时间过后才能获取promise的结果,此时promise处于reject状态

注意:如果当 pengding 状态进入到 reject 状态,这个错误又没有正确捕获的话,这个错误就会被抛到 JS 的全局

reslove 状态流转到 reject 状态测试

(function () {
  const res = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
    }, 300);
    setTimeout(() => {
      reject(new Error("error"));
    }, 500);
  });
  console.log("500ms", res);

  setTimeout(() => {
    console.log("800ms", res);
  }, 800);
})();
Copier après la connexion

打印出如下内容

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

可以发现!

在 300ms 的时候promise的状态已经切换到了resolve, 切换后永远也无法到达reject状态

  • pending 只能流转到 resolve 或者 reject;
  • resolvereject 不能互相流转;

使用 then,catch 捕获 promise 的结果

(function () {
  const res = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(3);
    }, 300);
  })
    .then((result) => {
      console.log("result", result);
    })
    .catch((error) => {
      console.log("error", error);
    });

  console.log("300ms", res);

  setTimeout(() => {
    console.log("800ms", res);
  }, 800);
})();
Copier après la connexion

打印出如下内容

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

可以发现

  • thenpromise 的状态流转到 reslove 状态可以拿到的结果
(function () {
  const res = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error("error-3"));
    }, 300);
  })
    .then((result) => {
      console.log("result", result);
    })
    .catch((error) => {
      console.log("error", error);
    });

  console.log("300ms", res);

  setTimeout(() => {
    console.log("800ms", res);
  }, 800);
})();
Copier après la connexion

打印出如下内容

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

可以发现

catchpromise 的状态流转到 reject 状态可以拿到的结果, 并且之前全局的 JS 错误已经可以被 catch 捕获到了

.then .catch 总结

  • resolved 状态的 Promise 会回调后面的第一个 .then
  • rejected 状态的 Promise 会回调后面的第一个 .catch
  • 任何一个 rejected 状态切后面没有 .catch 的 Promise 会造成 Js 环境的全局错误

Promise 相比 callback 优秀的地方

解决异步流程控制问题-回调地狱

我们继续之前面试的例子

使用 Promise 改造 之前的 interview 函数

function interview() {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        reject(new Error("fail"));
      }
    }, 1000);
  });
}

(function () {
  const res = interview();
  res
    .then((result) => {
      console.log("面试成功!我笑了");
    })
    .catch((error) => {
      console.log("面试失败!我哭了");
    });
})();
Copier après la connexion

.then 中抛出错误的情况测试

function interview() {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        reject(new Error("fail"));
      }
    }, 500);
  });
}

(function () {
  const promsie1 = interview();

  const promsie2 = promsie1.then((result) => {
    throw new Error("面试成功!我笑了,但是我拒绝了");
  });

  setTimeout(() => {
    console.log("promsie1", promsie1);
    console.log("promsie2", promsie2);
  }, 800);
})();
Copier après la connexion

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

以上代码可以看出 ,**.then返回一个全新的 Promise, 此 Promise 的结果状态是由 .then 的回调函数的结果来决定的

  • 如果回调函数最终是throw, 则进入 rejected
  • 如果回调函数最终是return Vous devez attendre un certain temps avant de pouvoir obtenir le résultat de la promesse. cette fois, la promesse est au statut réalisée

en attente de rejet du test de flux
function interview() {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        reject(new Error("fail"));
      }
    }, 500);
  });
}

(function () {
  const promsie1 = interview();

  const promsie2 = promsie1.catch((result) => {
    return "虽然面试失败,但我还是笑了";
  });

  setTimeout(() => {
    console.log("promsie1", promsie1);
    console.log("promsie2", promsie2);
  }, 800);
})();
Copier après la connexion

Imprimez ce qui suit content

Une analyse approfondie de Promise dans la programmation asynchrone NodejsUne analyse approfondie de Promise dans la programmation asynchrone Nodejs

🎜 Le résultat est conforme à nos attentes🎜🎜🎜Nous ne pouvons pas l'obtenir immédiatement< Le résultat de code>promesse A ce moment, promesse est dans le en attente</code. > état. Vous devez attendre un certain temps avant de pouvoir obtenir le résultat de <code>promesse. À ce stade, promesse est dans le rejeter. state🎜🎜
🎜Remarque : Si l'état pengding entre dans l'état reject, si cette erreur n'est pas capturée correctement, cette erreur sera renvoyée au JS global🎜

🎜flux de statut reslove pour rejeter le test de statut🎜🎜
function interview() {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        reject(new Error("fail"));
      }
    }, 500);
  });
}

(function () {
  const promsie1 = interview();

  const promsie2 = promsie1
    .then((result) => {
      return new Promise(function (resolve, reject) {
        setTimeout(() => {
          resolve("面试成功!,给我400ms 总结一下");
        }, 400);
      });
    })
    .catch((result) => {
      return new Promise(function (resolve, reject) {
        setTimeout(() => {
          resolve("面试失败,给我400ms 总结一下");
        }, 400);
      });
    });

  setTimeout(() => {
    console.log("800ms promsie1", promsie1);
    console.log("800ms promsie2", promsie2);
  }, 800);

  setTimeout(() => {
    console.log("1000ms promsie1", promsie1);
    console.log("1000ms promsie2", promsie2);
  }, 1000);
})();
Copier après la connexion
Copier après la connexion
🎜Imprimer le contenu suivant🎜🎜Une analyse approfondie de Promise dans la programmation asynchrone Nodejs🎜 🎜Peut être découvert ! 🎜🎜À 300 ms, l'état de promise a été basculé sur resolve Après le changement, il n'atteindra jamais l'état reject🎜🎜🎜<. code>en attente ne peut être transféré que vers resolve ou reject ;🎜🎜resolve et reject ne peuvent pas être transférés les uns aux autres ;🎜 🎜

🎜Utilisez then,catch pour capturer le résultat de la promesse🎜🎜
// round 面试第几轮
function interview(round) {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        const error = new Error("fail");
        reject({ round, error });
      }
    }, 500);
  });
}

(function () {
  interview(1)
    .then(() => {
      return interview(2);
    })
    .then(() => {
      return interview(3);
    })
    .then(() => {
      console.log("每轮面试都成功!我开心的笑了");
    })
    .catch((err) => {
      console.log(`第${err.round}轮面试失败了`);
    });
})();
Copier après la connexion
Copier après la connexion
🎜Imprimez le contenu suivant🎜🎜Une analyse approfondie de Promise dans la programmation asynchrone Nodejs🎜🎜peut être trouvé🎜🎜🎜alors< /code> est une <code>promesse</code > Le statut passe au statut <code>reslove et le résultat peut être obtenu🎜🎜
// round 面试第几轮
function interview(name) {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        const error = new Error("fail");
        reject({ name, error });
      }
    }, 500);
  });
}

(function () {
  Promise.all([interview("tenxun"), interview("ali"), interview("baidu")])
    .then(() => {
      console.log("每家公司都面试成功了");
    })
    .catch((err) => {
      console.log(`面试${err.name}失败了`);
    });
})();
Copier après la connexion
Copier après la connexion
🎜Imprimez le contenu suivant🎜🎜Une analyse approfondie de Promise dans la programmation asynchrone Nodejs🎜🎜Vous pouvez trouver🎜🎜catch< /code> est le flux d'état de <code>promise. Les résultats peuvent être obtenus lorsque l'état reject est atteint, et les erreurs JS globales précédentes peuvent déjà être capturées par catch 🎜🎜🎜.then .catch summary🎜🎜🎜🎜🎜résolu rappellera le premier .then🎜🎜🎜🎜rejeté La promesse dans l'état rappellera le premier .catch🎜🎜🎜🎜Tout commutateur d'état rejeté sans promesse de .catch< /code> provoquera une erreur globale dans l'environnement Js🎜🎜🎜<h2 data-id="heading-6">🎜Les avantages de Promise par rapport au rappel🎜🎜<h3 data-id="heading-7">🎜 Résoudre les problèmes de contrôle de processus asynchrone - l'enfer des rappels🎜🎜🎜Continuons l'exemple de l'interview précédente🎜<h4 data-id="heading-8">🎜Utilisez Promise pour transformer la fonction d'interview précédente🎜🎜rrreee<h4 data-id= "heading-9">🎜.puis pour tester la situation où une erreur est générée🎜🎜rrreee🎜<img src ="https://img.php.cn/upload/image/380/332/132/162562900612334Une analyse approfondie de Promise dans la programmation asynchrone Nodejs " title="162562900612334Une analyse approfondie de Promise dans la programmation asynchrone Nodejs" alt="Une analyse approfondie de Promise dans la programmation asynchrone Nodejs"/>🎜🎜Comme vous pouvez le voir dans le code ci-dessus, <code>**.then renvoie une toute nouvelle promesse. Le statut du résultat de cette La promesse est déterminée par le résultat de la fonction de rappel de .then🎜🎜🎜🎜Si la fonction de rappel est finalement throw, alors entrez rejeté🎜🎜🎜🎜Si la fonction de rappel est enfin retour, puis entrez le test de valeur normale en résolu🎜🎜🎜🎜🎜.catch🎜🎜rrreee🎜 🎜🎜

.catch 返回一个全新的 Promise, 此 Promise 的结果状态是由 .catch 的回调函数的结果来决定的

  • 如果回调函数最终是throw, 则进入 rejected
  • 如果回调函数最终是return,则进入 resolved

.catch,.then 里面再返回 Promise

function interview() {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        reject(new Error("fail"));
      }
    }, 500);
  });
}

(function () {
  const promsie1 = interview();

  const promsie2 = promsie1
    .then((result) => {
      return new Promise(function (resolve, reject) {
        setTimeout(() => {
          resolve("面试成功!,给我400ms 总结一下");
        }, 400);
      });
    })
    .catch((result) => {
      return new Promise(function (resolve, reject) {
        setTimeout(() => {
          resolve("面试失败,给我400ms 总结一下");
        }, 400);
      });
    });

  setTimeout(() => {
    console.log("800ms promsie1", promsie1);
    console.log("800ms promsie2", promsie2);
  }, 800);

  setTimeout(() => {
    console.log("1000ms promsie1", promsie1);
    console.log("1000ms promsie2", promsie2);
  }, 1000);
})();
Copier après la connexion
Copier après la connexion

Une analyse approfondie de Promise dans la programmation asynchrone Nodejs

如果在 .catch,.then 中 返回 Promise, 则会等待此 Promise 的执行结果

如果回调函数最终 return 了 Promise,该 promise 和回调函数的 return 的 Promsie 状态保持一致, 这就表示了可以 在 Promise 的链式调用里面串行的执行多个异步任务!

Promise 实现多轮面试-串行

// round 面试第几轮
function interview(round) {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        const error = new Error("fail");
        reject({ round, error });
      }
    }, 500);
  });
}

(function () {
  interview(1)
    .then(() => {
      return interview(2);
    })
    .then(() => {
      return interview(3);
    })
    .then(() => {
      console.log("每轮面试都成功!我开心的笑了");
    })
    .catch((err) => {
      console.log(`第${err.round}轮面试失败了`);
    });
})();
Copier après la connexion
Copier après la connexion

Promise 的 .then .catch 把回调地狱变成了一段线性的代码!

Promise 实现多加公司面试-并行

// round 面试第几轮
function interview(name) {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (Math.random() > 0.4) {
        // resolve, reject 只能接受一个参数
        resolve("success");
      } else {
        const error = new Error("fail");
        reject({ name, error });
      }
    }, 500);
  });
}

(function () {
  Promise.all([interview("tenxun"), interview("ali"), interview("baidu")])
    .then(() => {
      console.log("每家公司都面试成功了");
    })
    .catch((err) => {
      console.log(`面试${err.name}失败了`);
    });
})();
Copier après la connexion
Copier après la connexion

更多编程相关知识,请访问:编程视频!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:juejin.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal