>웹 프론트엔드 >JS 튜토리얼 >Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

青灯夜游
青灯夜游앞으로
2021-07-07 11:44:501757검색

이 글에서는 비동기 프로그래밍의 NodejsPromise를 살펴보고 Promise가 콜백보다 나은 점을 소개합니다.

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

【추천 학습: "nodejs tutorial"】

Promise란 무엇입니까

Promise는 비동기 프로그래밍을 위한 솔루션입니다!

  • 현재 이벤트 루프는 결과를 얻을 수 없지만 미래 이벤트 루프는 결과를 제공합니다
  • 는 상태 기계입니다
    • pengding
    • resolved
    • reejectd

상태 흐름은 어떻습니까?

플로우 테스트 해결 대기 중

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

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

다음 내용을 인쇄하세요

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

결과는 우리의 기대와 일치합니다

  • 약속의 결과를 즉시 얻을 수는 없습니다. 현재 promisepending 상태입니다 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);
})();

打印出如下内容

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

结果是符合我们的预期的

  • 我们无法立即获取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);
})();

打印出如下内容

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

可以发现!

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

打印出如下内容

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

可以发现

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

打印出如下内容

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

可以发现

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("面试失败!我哭了");
    });
})();

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

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

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

  • 如果回调函数最终是throw, 则进入 rejected
  • 如果回调函数最终是return promise의 결과를 얻으려면 일정 시간을 기다려야 합니다. 이번에는 약속fulfilled 상태입니다

흐름 테스트 거부 대기 중
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);
})();

다음을 인쇄하세요 content

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

🎜 결과는 기대했던 것과 일치합니다🎜🎜🎜즉시 얻을 수는 없습니다약속 현재 약속보류 중입니다. > 상태입니다. promise의 결과를 얻으려면 일정 시간을 기다려야 합니다. 이때 promisereject에 있습니다. state🎜🎜
🎜참고: pengding 상태가 reject 상태로 전환되는 경우 이 오류가 올바르게 캡처되지 않으면 이 오류가 전역 JS🎜에 발생합니다.

🎜reslove 상태 테스트를 거부하는 흐름🎜🎜
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);
})();
🎜다음 내용을 인쇄하세요🎜🎜Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석🎜 🎜발견 가능! 🎜🎜300ms가 되면 promise 상태가 resolve로 전환됩니다. 전환 후에는 결코 reject 상태에 도달하지 않습니다🎜🎜🎜보류는 해결 또는 거부로만 전송할 수 있습니다.🎜🎜해결거부는 전송할 수 없습니다. 🎜 🎜

🎜그런 다음 catch를 사용하여 약속의 결과를 캡처하세요🎜🎜
// 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}轮面试失败了`);
    });
})();
🎜다음 내용을 인쇄하세요🎜🎜Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석🎜🎜찾을 수 있습니다🎜🎜🎜그러면는 <code>promise입니다. 상태는 reslove 상태로 흐르고 결과를 얻을 수 있습니다🎜🎜
// 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}失败了`);
    });
})();
🎜다음 내용을 인쇄하세요🎜🎜Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석🎜🎜찾을 수 있습니다🎜🎜catch는 <code>promise의 상태 흐름입니다. reject 상태에 도달하면 결과를 얻을 수 있으며, 이전 전역 JS 오류는 이미 catch로 캡처할 수 있습니다. 🎜🎜🎜.then .catch summary🎜🎜🎜🎜🎜resolved 상태의 Promise는 첫 번째 .then🎜🎜🎜🎜rejected 상태의 Promise는 .catch .catch🎜🎜🎜🎜모든 rejected 상태 스위치를 콜백합니다. /code>는 Js 환경에서 전역 오류를 발생시킵니다🎜🎜🎜

🎜콜백과 비교한 Promise의 장점🎜🎜

🎜 비동기 프로세스 제어 문제 해결 - 콜백 지옥🎜🎜🎜이전 인터뷰의 예를 계속 이어가겠습니다🎜

🎜Promise를 사용하여 이전 인터뷰 기능을 변환하세요🎜🎜rrreee

🎜.그런 다음 오류가 발생하는 상황을 테스트하려면🎜🎜rrreee🎜Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석🎜🎜위 코드에서 볼 수 있듯이 **.then은 새로운 Promise를 반환합니다. 이 결과 상태는 Promise는 .then🎜🎜🎜🎜콜백 함수가 결국 throw인 경우 거부됨🎜🎜🎜🎜을 입력합니다. 마지막으로 return인 경우, received🎜🎜🎜🎜🎜.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);
})();

Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석

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

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

위 내용은 Nodejs 비동기 프로그래밍의 Promise에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제