Heim  >  Artikel  >  Web-Frontend  >  Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

青灯夜游
青灯夜游nach vorne
2021-07-07 11:44:501723Durchsuche

Dieser Artikel führt Sie durch NodejsPromise in der asynchronen Programmierung und stellt vor, warum Promise besser ist als Callback.

Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

【Empfohlenes Lernen: „nodejs-Tutorial“】

Was ist Promise?

Promise ist eine Lösung für asynchrone Programmierung!

  • Die aktuelle Ereignisschleife kann das Ergebnis nicht abrufen, aber die zukünftige Ereignisschleife wird Ihnen das Ergebnis liefern.
  • ist eine Zustandsmaschine Code?
    • Flusstest muss noch gelöst werden
    • (function () {
        const res = new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve();
          }, 500);
        });
        console.log("500ms", res);
      
        setTimeout(() => {
          console.log("800ms", res);
        }, 800);
      })();
    • Den folgenden Inhalt drucken

Das Ergebnis entspricht unseren Erwartungen

Wir können das Ergebnis von promise nicht sofort erhalten, Zu diesem Zeitpunkt befindet sich promise im Status ausstehend

Sie müssen eine gewisse Zeit warten, bevor Sie das Ergebnis von promise erhalten können Dieses Mal befindet sich promise im Status erfüllt

steht zur Ablehnung des Flusstests ausEine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

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

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

Drucken Sie Folgendes aus Inhalt

    Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs
  • promise的结果,此时promise处于pending状态
  • 必须等待一段时间过后才能获取promise的结果,此时promise处于fulfilled状态

pending 到 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);
})();

打印出如下内容

Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

结果是符合我们的预期的

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

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

reslove 状态流转到 reject 状态测试

(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);
})();

打印出如下内容

Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

可以发现!

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

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

使用 then,catch 捕获 promise 的结果

(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);
})();

打印出如下内容

Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

可以发现

  • thenpromise 的状态流转到 reslove 状态可以拿到的结果
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("面试失败!我哭了");
    });
})();

打印出如下内容

Eine eingehende Analyse von Promise in der asynchronen Programmierung von 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"));
      }
    }, 500);
  });
}

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

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

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

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

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);
})();

Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

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

  • 如果回调函数最终是throw, 则进入 rejected
  • 如果回调函数最终是return Das Ergebnis entspricht unseren Erwartungen. Wir können es nicht sofort erhalten > Zustand. Sie müssen eine gewisse Zeit warten, bevor Sie das Ergebnis von promise erhalten können. Zu diesem Zeitpunkt befindet sich promise im reject state
Hinweis: Wenn der pengding-Status in den reject-Status übergeht und dieser Fehler nicht korrekt erfasst wird, wird dieser Fehler an das globale JS

geworfen

Statusfluss neu definieren, um Statustest abzulehnen

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);
})();

Den folgenden Inhalt ausdruckenEine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs

Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs🎜 🎜Kann entdeckt werden! 🎜🎜Bei 300 ms wurde der Status von promise auf resolve umgestellt. Nach dem Umschalten wird der Status reject nie erreicht🎜🎜🎜pending kann nur auf resolve oder reject übertragen werden; 🎜🎜resolve und reject nicht aufeinander übertragen werden;🎜 🎜

🎜Verwenden Sie then,catch, um das Ergebnis des Versprechens zu erfassen🎜🎜
// 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}轮面试失败了`);
    });
})();
🎜Drucken Sie den folgenden Inhalt aus🎜🎜Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs🎜🎜kann gefunden werden🎜🎜🎜dann ist <code>promise Der Status geht in den Status reslove über und das Ergebnis kann abgerufen werden🎜🎜
// 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}失败了`);
    });
})();
🎜Den folgenden Inhalt ausdrucken🎜🎜Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs🎜🎜Sie finden🎜🎜catch ist der Statusfluss von <code>promise. Die Ergebnisse können erhalten werden, wenn der Status reject erreicht ist und die vorherigen globalen JS-Fehler bereits von catch erfasst werden können 🎜🎜🎜.then .catch summary🎜🎜🎜🎜🎜resolved ruft den ersten .then🎜🎜🎜🎜rejected Das Promise im Status ruft den ersten .catch zurück. 🎜🎜🎜🎜Jeder rejected-Statuswechsel ohne ein Promise von .catch verursacht einen globalen Fehler in der Js-Umgebung🎜🎜🎜<h2 data-id="heading-6">🎜Die Vorteile von Promise im Vergleich zum Rückruf🎜🎜<h3 data-id="heading-7">🎜 Probleme bei der asynchronen Prozesssteuerung lösen – Callback-Hölle🎜🎜🎜Lassen Sie uns das Beispiel aus dem vorherigen Interview fortsetzen🎜<h4 data-id="heading-8">🎜Verwenden Sie Promise, um die Funktion des vorherigen Interviews umzuwandeln🎜🎜rrreee<h4 data-id="heading-9">🎜.then, um die Situation zu testen, in der ein Fehler ausgegeben wird🎜🎜rrreee🎜<img src="https://img.php.cn/upload/image/380/332/132/162562900612334Eine%20eingehende%20Analyse%20von%20Promise%20in%20der%20asynchronen%20Programmierung%20von%20Nodejs%20" title="162562900612334Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs" alt="Eine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs">🎜🎜Wie Sie dem obigen Code entnehmen können, gibt <code>**.then ein brandneues Promise zurück. Der Ergebnisstatus davon Das Versprechen wird durch das Ergebnis der Rückruffunktion von .then bestimmt. 🎜🎜🎜🎜Wenn die Rückruffunktion schließlich throw ist, geben Sie „rejected“ ein ist schließlich return, dann geben Sie den Normalwerttest in gelöst ein🎜🎜🎜🎜🎜.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);
})();

Eine eingehende Analyse von Promise in der asynchronen Programmierung von 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}轮面试失败了`);
    });
})();

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}失败了`);
    });
})();

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

Das obige ist der detaillierte Inhalt vonEine eingehende Analyse von Promise in der asynchronen Programmierung von Nodejs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen