{"@attributes":{"version":"2.0"},"channel":{"title":"\u952e\u843d\u4e91\u8d77","link":"https:\/\/jancat.github.io\/","description":"Recent content on \u952e\u843d\u4e91\u8d77","generator":"Hugo -- gohugo.io","language":"zh","lastBuildDate":"Sun, 09 May 2021 20:48:09 +0800","item":[{"title":"CSS Overflow \u7384\u5b66","link":"https:\/\/jancat.github.io\/post\/2021\/css-overflow-metaphysics\/","pubDate":"Sun, 09 May 2021 20:48:09 +0800","guid":"https:\/\/jancat.github.io\/post\/2021\/css-overflow-metaphysics\/","description":"<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210509210016035.png\" alt=\"image-20210509210016035\"><\/p>\n<p>\u9875\u9762\u7684\u6eda\u52a8\u5e03\u5c40\u8ddf CSS <code>overflow<\/code> \u5c5e\u6027\u7684\u8bbe\u7f6e\u606f\u606f\u76f8\u5173\uff0c\u5173\u7cfb\u5230\u67d0\u5757\u6ea2\u51fa\u5c4f\u5e55\uff08\u5bb9\u5668\uff09\u7684\u5143\u7d20\u90e8\u5206\u80fd\u5426\u6b63\u5e38\u6eda\u52a8\u51fa\u73b0\u5728\u89c6\u53e3\u4e2d\uff0c\u6216\u8005\u76f8\u5bf9\u4e8e\u6839\u5143\u7d20\u5b9a\u4f4d\u7684\u5143\u7d20\u662f\u5426\u5177\u6709\u540c\u6b65\u6eda\u52a8\u7684\u80fd\u529b\u3002overflow \u4ece\u5355\u4e2a\u5143\u7d20\u7684\u89c6\u89d2\u7406\u89e3\u4e0d\u96be\uff0c\u4f46\u662f <code>overflow<\/code> \u7684\u5411\u4e0a\u4f20\u64ad\u7279\u6027\uff0c\u4f7f\u5f97\u5b83\u52a8\u8f84\u5f71\u54cd\u9875\u9762\u5e03\u5c40\uff0c\u6700\u540e\u6eda\u4e0d\u6eda\u5f97\u52a8\u5c31\u4e0d\u597d\u8bf4\u4e86\u3002<\/p>\n<p>\u672c\u6587\u5c06\u7528\u4e00\u4e2a demo \u6765\u89c2\u6d4b overflow\u3001scroll \u7684\u5177\u4f53\u8868\u73b0\u3002<\/p>\n<h2 id=\"overflow-\u76f8\u5173\u5c5e\u6027\">overflow \u76f8\u5173\u5c5e\u6027<\/h2>\n<p>\u8ddf <code>overflow<\/code> \u76f8\u5173\u7684\u5143\u7d20\u5c5e\u6027\u6709 <code>offsetHeight<\/code>\u3001<code>clientHeight<\/code>\u3001 <code>scrollHeight<\/code>\u3001<code>scrollTop<\/code> \uff0c\u5b83\u4eec\u7684\u8ba1\u7b97\u65b9\u5f0f\u4e3a\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><span class=\"lnt\">8\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ \u5143\u7d20\u5185\u90e8\u5c3a\u5bf8\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">clientHeight<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">content<\/span> <span class=\"nx\">height<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">padding<\/span>\n<span class=\"c1\">\/\/ \u5143\u7d20\u5e03\u5c40\u5c3a\u5bf8\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">offsetHeight<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">content<\/span> <span class=\"nx\">height<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">border<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">padding<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">scroll<\/span> <span class=\"nx\">bar<\/span>\n<span class=\"c1\">\/\/ \u5143\u7d20\u5185\u5bb9\u5c3a\u5bf8\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">scrollHeight<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">content<\/span> <span class=\"nx\">height<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">padding<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">pseudo<\/span> <span class=\"nx\">element<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">overflow<\/span>\n<span class=\"c1\">\/\/ \u5143\u7d20\u5782\u76f4\u6eda\u52a8\u8ddd\u79bb\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">scrollTop<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">\u5b50\u5143\u7d20\u9876\u90e8\u8ddd\u79bb\u53ef\u89c6\u5185\u5bb9\u9876\u90e8\u7684\u9ad8\u5ea6<\/span><span class=\"err\">\uff08<\/span><span class=\"nx\">\u975e\u6eda\u52a8\u5143\u7d20<\/span> <span class=\"nx\">scrollTop<\/span> <span class=\"nx\">\u4e3a<\/span> <span class=\"mi\">0<\/span><span class=\"err\">\uff09<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><code>scrollHeight<\/code> \u76f8\u6bd4 <code>offsetHeight<\/code> \uff0c\u5305\u542b\u4e86\u5b50\u5143\u7d20\u6ea2\u51fa\u7684\u9ad8\u5ea6\u3002<\/p>\n<p>demo \u4e2d\u4f1a\u89c2\u5bdf\u6bcf\u4e2a\u5143\u7d20\u7684\u8fd9\u51e0\u4e2a\u503c\uff08\u6700\u65b0\u7248 Chrome \u4e0b\u6d4b\u8bd5 \uff09\uff0c\u7384\u5b66\u8fd8\u5f97\u7528\u56fe\u548c\u6570\u636e\u8bf4\u8bdd\u3002<\/p>\n<h2 id=\"overflow-demo\">overflow demo<\/h2>\n<p>demo \u6700\u5f00\u59cb\u7684\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-html\" data-lang=\"html\"><span class=\"p\">&lt;<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">.<\/span><span class=\"nc\">container<\/span> <span class=\"p\">{<\/span>\n\t\t<span class=\"k\">border<\/span><span class=\"p\">:<\/span> <span class=\"mi\">10<\/span><span class=\"kt\">px<\/span> <span class=\"kc\">solid<\/span> <span class=\"n\">Teal<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">content<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">500<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">background<\/span><span class=\"p\">:<\/span> <span class=\"n\">LightSeaGreen<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n\n<span class=\"p\">&lt;<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">&lt;<\/span><span class=\"nt\">container<\/span> <span class=\"na\">class<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;container&#34;<\/span><span class=\"p\">&gt;<\/span>\n  \t<span class=\"p\">&lt;<\/span><span class=\"nt\">content<\/span> <span class=\"na\">class<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;content&#34;<\/span><span class=\"p\">&gt;&lt;\/<\/span><span class=\"nt\">content<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">&lt;\/<\/span><span class=\"nt\">container<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5f53\u5bb9\u5668\u5143\u7d20 <code>container<\/code> \u6ca1\u6709\u8bbe\u7f6e <code>height<\/code> \u65f6\uff0c\u5b50\u5143\u7d20 <code>content<\/code> \u7684\u9ad8\u5ea6 <code>height: 500px<\/code> \u81ea\u52a8\u6491\u5f00\u7236\u5143\u7d20\uff0c<code>container<\/code> \u9ad8\u5ea6\uff08<code>offsetHeight<\/code>\uff09\u6b64\u65f6\u4e3a <code>content<\/code> \u7684\u9ad8\u5ea6 + <code>container<\/code>\u6c34\u5e73 border \u9ad8\u5ea6 = 520px<\/p>\n<p><!-- raw HTML omitted --><\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>container<\/td>\n<td>520<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"\u7236\u5143\u7d20\u56fa\u5b9a\u9ad8\u5ea6\">\u7236\u5143\u7d20\u56fa\u5b9a\u9ad8\u5ea6<\/h3>\n<p>\u5728\u4e0a\u9762 demo \u7684\u57fa\u7840\u4e0a\u505a\u4e9b\u6539\u52a8\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-html\" data-lang=\"html\"><span class=\"p\">&lt;<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">.<\/span><span class=\"nc\">container<\/span> <span class=\"p\">{<\/span>\n\t\t<span class=\"k\">border<\/span><span class=\"p\">:<\/span> <span class=\"mi\">10<\/span><span class=\"kt\">px<\/span> <span class=\"kc\">solid<\/span> <span class=\"n\">Teal<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">300<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">content<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">500<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">background<\/span><span class=\"p\">:<\/span> <span class=\"n\">LightSeaGreen<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n\n<span class=\"p\">&lt;<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">&lt;<\/span><span class=\"nt\">container<\/span> <span class=\"na\">class<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;container&#34;<\/span><span class=\"p\">&gt;<\/span>\n  \t<span class=\"p\">&lt;<\/span><span class=\"nt\">content<\/span> <span class=\"na\">class<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;content&#34;<\/span><span class=\"p\">&gt;<\/span>\n    \toverflow content\n    <span class=\"p\">&lt;\/<\/span><span class=\"nt\">content<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">&lt;\/<\/span><span class=\"nt\">container<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">&lt;<\/span><span class=\"nt\">p<\/span><span class=\"p\">&gt;<\/span>\n    behind element\n  <span class=\"p\">&lt;\/<\/span><span class=\"nt\">p<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5f53\u8bbe\u7f6e\u4e86 <code>container<\/code> <code>height: 300px;<\/code> \u540e\uff0c<code>content<\/code> \u9ad8\u5ea6\u6ea2\u51fa\uff0c\u56e0\u4e3a\u7236\u5143\u7d20\u9ed8\u8ba4\u6ea2\u51fa\u4e0d\u88c1\u526a\uff08<code>overflow: visible<\/code>\uff09\uff0c\u53ef\u4ee5\u770b\u5230 <code>content<\/code> \u6ea2\u51fa\u7684\u90e8\u5206\u8986\u76d6\u4e86 <code>container<\/code> \u7684 bottom border\uff0c\u5e76\u4e14 <code> content<\/code> \u6ea2\u51fa\u5185\u5bb9\u76f4\u63a5\u8986\u76d6\u5728\u4e86 <code>container<\/code> \u76f8\u90bb\u7684 behind \u5143\u7d20\u4e0a\uff08\u89c1 <strong>overflow content<\/strong>\uff09\uff0c\u4f46 <code>content<\/code> \u7684 <code>background<\/code> \u5c42\u53e0\u7b49\u7ea7\u5c0f\u4e8e behind \u5143\u7d20\u7684 <code>background<\/code>\uff0c\u6240\u4ee5 behind \u5143\u7d20\u7684 <code>background<\/code> \u5728\u4e0a\u9762\uff08\u7384\u4e0d\u7384\uff09\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210207212401610.png\" alt=\"\"><\/p>\n<p>\u6240\u4ee5\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u6ea2\u51fa\u7684\u5185\u5bb9\u4e0d\u4f1a\u5f71\u54cd\u6b63\u5e38\u7684\u6587\u6863\u6d41\uff0c\u76f4\u63a5\u8986\u76d6\u5728\u7236\u5143\u7d20\u540e\u9762\u7684\u5143\u7d20\u4e0a\uff0c\u53ef\u80fd\u5f71\u54cd\u6b63\u5e38\u9875\u9762\u4fe1\u606f\u7684\u83b7\u53d6\u3002<\/p>\n<p>\u6b64\u65f6 <code>container<\/code> \u548c <code>content<\/code> \u5143\u7d20\u7684 <code>scrollHeight<\/code> \u90fd\u4e3a 500 px\uff0c\u56e0\u4e3a\u7236\u5143\u7d20\u7684 <code>scrollHeight<\/code> \u4f1a\u5305\u542b\u5b50\u5143\u7d20\u7684\u6ea2\u51fa\u90e8\u5206\uff0c\u4f46\u4e0d\u5305\u542b border\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>container<\/td>\n<td>320<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"\u7236\u5143\u7d20-overflow-auto\">\u7236\u5143\u7d20 overflow: auto<\/h3>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-html\" data-lang=\"html\"><span class=\"p\">&lt;<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">.<\/span><span class=\"nc\">container<\/span> <span class=\"p\">{<\/span>\n\t\t<span class=\"k\">border<\/span><span class=\"p\">:<\/span> <span class=\"mi\">10<\/span><span class=\"kt\">px<\/span> <span class=\"kc\">solid<\/span> <span class=\"n\">Teal<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">300<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">overflow<\/span><span class=\"p\">:<\/span> <span class=\"kc\">auto<\/span><span class=\"p\">;<\/span> <span class=\"c\">\/* add it *\/<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8bbe\u7f6e <code>container<\/code> <code>overflow: auto<\/code>\uff0c\u8ba9 <code>content<\/code> \u6ea2\u51fa\u7684\u5185\u5bb9\u9690\u85cf\uff0c<strong>\u53ef\u89c6\u533a\u57df<\/strong>\u4e3a\u7236\u5143\u7d20\u7684 padding area\uff08height 300 px\uff09\uff0c\u7236\u5143\u7d20\u5f00\u542f\u6eda\u52a8\uff0c\u53ef\u89c6\u533a\u57df\u51fa\u73b0\u5782\u76f4\u6eda\u52a8\u6761\u3002<\/p>\n<blockquote>\n<p>\u5728 Mac \u7cfb\u7edf\u4e2d\uff0c\u9875\u9762\u4e2d\u51fa\u73b0\u7684\u6eda\u52a8\u6761\u662f\u60ac\u6d6e\u8986\u76d6\u5728\u5143\u7d20\u4e0a\uff0c\u4e0d\u5360\u7528\u6eda\u52a8\u5143\u7d20\u7684\u5bbd\u5ea6\uff0c\u5373 <code>scrollElement.offsetWidth<\/code> \u4e2d\u5305\u542b\u7684\u6eda\u52a8\u6761\u5bbd\u5ea6\u4e3a 0\u3002<\/p>\n<\/blockquote>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210208210936691.png\" alt=\"\"><\/p>\n<p>\u5f53 <code>container<\/code> \u6eda\u52a8\u5230\u5e95\u90e8\uff0c<code>container.scrollTop<\/code> \u6eda\u52a8\u7684\u503c\u4e3a <code>content<\/code> \u9876\u90e8\uff08\u4e0d\u53ef\u89c1\uff09\u5230 <code>container<\/code> <strong>\u53ef\u89c6\u533a\u57df<\/strong> \u9876\u90e8\u7684\u8ddd\u79bb\uff0c<code>content<\/code> \u7684\u9ad8\u5ea6 500 px \u5728\u53ef\u89c6\u533a\u57df\u663e\u793a\u5b8c 300 px \u540e\uff0c\u6eda\u52a8\u5230\u4e0a\u9762\u5269\u4e0b\u7684\u4e0d\u53ef\u89c1\u533a\u57df\u9ad8\u5ea6\u4e3a 200px\uff0c\u5373\u7b49\u4e8e <code>container<\/code> \u7684\u6eda\u52a8\u8ddd\u79bb <code>scrollTop<\/code> 200 px\u3002<code>cotainer<\/code> \u53ef\u89c6\u533a\u57df\u7684\u9ad8\u5ea6\u4e3a <code>clientHeight<\/code> \uff08\u4e0d\u5305\u62ec border\u3001\u6ea2\u51fa\uff09300 px\u3002<\/p>\n<p>\u4e0b\u9762\u7684\u7b49\u5f0f\u53ef\u4ee5\u7528\u6765\u5224\u65ad <code>container<\/code> \u662f\u5426\u5782\u76f4\u6eda\u52a8\u5230\u6700\u5e95\u90e8\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">container<\/span><span class=\"p\">.<\/span><span class=\"nx\">scrollTop<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">container<\/span><span class=\"p\">.<\/span><span class=\"nx\">clientHeight<\/span> <span class=\"o\">==<\/span> <span class=\"nx\">container<\/span><span class=\"p\">.<\/span><span class=\"nx\">scrollHeight<\/span> <span class=\"o\">==<\/span> <span class=\"nx\">content<\/span><span class=\"p\">.<\/span><span class=\"nx\">offsetHeight<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u7531\u4e8e <code>content<\/code> \u4e0d\u662f\u53ef\u6eda\u52a8\u5143\u7d20\uff08<code>content<\/code> \u5b50\u5143\u7d20\u6ca1\u6709\u6ea2\u51fa\uff09\uff0c\u6240\u4ee5\u5728 <code>container<\/code> \u6eda\u52a8\u8fc7\u7a0b\u4e2d\uff0c<code>content.scrollTop<\/code> \u59cb\u7ec8\u4e3a 0\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>container<\/td>\n<td>320<\/td>\n<td>500<\/td>\n<td>200<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"\u7236\u5143\u7d20-overflow-hidden\">\u7236\u5143\u7d20 overflow: hidden<\/h3>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-html\" data-lang=\"html\"><span class=\"p\">&lt;<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">.<\/span><span class=\"nc\">container<\/span> <span class=\"p\">{<\/span>\n\t\t<span class=\"k\">border<\/span><span class=\"p\">:<\/span> <span class=\"mi\">10<\/span><span class=\"kt\">px<\/span> <span class=\"kc\">solid<\/span> <span class=\"n\">Teal<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">300<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">overflow<\/span><span class=\"p\">:<\/span> <span class=\"kc\">hidden<\/span><span class=\"p\">;<\/span> <span class=\"c\">\/* add it *\/<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8bbe\u7f6e <code>container<\/code> <code>overflow: hidden<\/code> \u540e\uff0c<code>content<\/code> \u6ea2\u51fa\u7684\u5185\u5bb9\u88ab\u88c1\u526a\u9690\u85cf\uff0c\u65e0\u6cd5\u901a\u8fc7\u524d\u7aef\u4ea4\u4e92\u65b9\u5f0f\u6eda\u52a8\u5143\u7d20\uff0c\u4f46\u4ecd\u7136\u53ef\u4ee5\u7528 JS \u63a7\u5236 <code>container<\/code> \u7684\u6eda\u52a8\u4f4d\u7f6e\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">container<\/span><span class=\"p\">.<\/span><span class=\"nx\">scrollTo<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">100<\/span><span class=\"p\">)<\/span>\n<span class=\"nx\">container<\/span><span class=\"p\">.<\/span><span class=\"nx\">scrollTop<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">100<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210209202040755.png\" alt=\"\"><\/p>\n<p>\u6b64\u65f6 <code>content<\/code> \u6ea2\u51fa\u5185\u5bb9\u867d\u7136\u88ab\u88c1\u526a\uff0c\u4f46\u4e0d\u5f71\u54cd <code>container.scrollHeight<\/code> \u7684\u503c\uff08500 px\uff09\uff0c\u56e0\u4e3a\u8fd8\u5b58\u5728\u6ea2\u51fa.<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>container<\/td>\n<td>320<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"\u9875\u9762\u5bb9\u5668\u5e03\u5c40\">\u9875\u9762\u5bb9\u5668\u5e03\u5c40<\/h2>\n<p>\u5f53\u521b\u5efa\u9875\u9762\u5bb9\u5668\u5e03\u5c40\u65f6\uff0c\u5bb9\u5668\u5143\u7d20 <code>overflow<\/code> \u7684\u8bbe\u7f6e\u4f1a\u5f71\u54cd\u5230\u9876\u7ea7\u5143\u7d20\uff08<code>html<\/code>\u3001<code>body<\/code>\u3001<code>root<\/code>\uff09\u7684\u6eda\u52a8\u533a\u57df\u3002<\/p>\n<p>\u5047\u8bbe\u9875\u9762\u7a97\u53e3\u7684\u89c6\u53e3\u9ad8\u5ea6\u4e3a 400 px\uff0c<code>root<\/code> \u6839\u5143\u7d20\u9ad8\u5ea6\u6491\u6ee1\u89c6\u53e3\u9ad8\u5ea6\uff08<code>height: 100%<\/code>\uff09\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-html\" data-lang=\"html\"><span class=\"p\">&lt;<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"nt\">html<\/span><span class=\"o\">,<\/span> <span class=\"nt\">body<\/span><span class=\"o\">,<\/span> <span class=\"p\">.<\/span><span class=\"nc\">root<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">100<\/span><span class=\"kt\">%<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">container<\/span> <span class=\"p\">{<\/span>\n\t\t<span class=\"k\">border<\/span><span class=\"p\">:<\/span> <span class=\"mi\">10<\/span><span class=\"kt\">px<\/span> <span class=\"kc\">solid<\/span> <span class=\"n\">Teal<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">300<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">overflow<\/span><span class=\"p\">:<\/span> <span class=\"kc\">hidden<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">content<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">500<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">background<\/span><span class=\"p\">:<\/span> <span class=\"n\">LightSeaGreen<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n\n<span class=\"p\">&lt;<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">&lt;<\/span><span class=\"nt\">root<\/span> <span class=\"na\">class<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;root&#34;<\/span><span class=\"p\">&gt;<\/span>\n    <span class=\"p\">&lt;<\/span><span class=\"nt\">container<\/span> <span class=\"na\">class<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;container&#34;<\/span><span class=\"p\">&gt;<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">content<\/span> <span class=\"na\">class<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;content&#34;<\/span><span class=\"p\">&gt;<\/span>\n        overflow content\n      <span class=\"p\">&lt;\/<\/span><span class=\"nt\">content<\/span><span class=\"p\">&gt;<\/span>\n    <span class=\"p\">&lt;\/<\/span><span class=\"nt\">container<\/span><span class=\"p\">&gt;<\/span>\n\t<span class=\"p\">&lt;\/<\/span><span class=\"nt\">root<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">body<\/span><span class=\"p\">&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210209215818858.png\" alt=\"\"><\/p>\n<p><code>container<\/code> \u4e0d\u7ba1\u8bbe\u7f6e <code>overflow: auto<\/code> \u8fd8\u662f <code>overflow: hidden<\/code> \uff0c<code>container<\/code> \u662f\u5426\u6eda\u52a8\u4e0d\u5f71\u54cd <code>container<\/code> \u672c\u8eab\u7684\u9ad8\u5ea6\u6ca1\u6709\u6ea2\u51fa <code>root<\/code> \u8fd9\u4e2a\u4e8b\u5b9e\uff0c  \u6240\u4ee5 <code>root<\/code> \u7684 <code>scrollHeight<\/code> \u4e0d\u5305\u542b <code>content<\/code> \u7684\u6ea2\u51fa\u5185\u5bb9\uff0c\u8fd8\u662f\u7b49\u4e8e\u81ea\u8eab\u9ad8\u5ea6\uff08<code> root.scrollHeight == root.offsetHeight == 400px<\/code>\uff09\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>html<\/td>\n<td>400<\/td>\n<td>400<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>body<\/td>\n<td>400<\/td>\n<td>400<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>root<\/td>\n<td>400<\/td>\n<td>400<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>container<\/td>\n<td>300<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u540c\u6837\u5730\uff0c<code>container<\/code> \u8bbe\u7f6e <code>height: 100%; overflow: auto<\/code> \u540e\uff0c\u5373\u4f7f\u4ece\u89c6\u89c9\u4e0a\u770b\u6574\u4e2a\u9875\u9762\u90fd\u6eda\u52a8\u4e86\uff0c\u4f46<code>root.scrollHeight<\/code> \u8fd8\u662f 400 px\uff0c\u6eda\u52a8\u53ea\u662f\u53d1\u751f\u5728 <code>container<\/code> \u5143\u7d20\u4e0a\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-html\" data-lang=\"html\"><span class=\"p\">&lt;<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"nt\">html<\/span><span class=\"o\">,<\/span> <span class=\"nt\">body<\/span><span class=\"o\">,<\/span> <span class=\"p\">.<\/span><span class=\"nc\">root<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">100<\/span><span class=\"kt\">%<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">container<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">100<\/span><span class=\"kt\">%<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">overflow<\/span><span class=\"p\">:<\/span> <span class=\"kc\">auto<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">content<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">500<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">background<\/span><span class=\"p\">:<\/span> <span class=\"n\">LightSeaGreen<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">&lt;\/<\/span><span class=\"nt\">style<\/span><span class=\"p\">&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210222135745915.png\" alt=\"\"><\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>html<\/td>\n<td>400<\/td>\n<td>400<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>body<\/td>\n<td>400<\/td>\n<td>400<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>root<\/td>\n<td>400<\/td>\n<td>400<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>container<\/td>\n<td>400<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"\u89e6\u53d1\u60ac\u6d6e\">\u89e6\u53d1\u60ac\u6d6e<\/h3>\n<p>\u5982\u679c\u6709\u60ac\u6d6e\u5143\u7d20\u548c\u89e6\u53d1\u5143\u7d20\u662f\u76f8\u5bf9\u4e8e <code>html<\/code> \u5143\u7d20\u6765\u5b9a\u4f4d\u504f\u79fb\u8ddd\u79bb\u7684\uff08\u6bd4\u5982\u60ac\u6d6e\u63d0\u793a\u3001\u4e0b\u62c9\u83dc\u5355\uff09\uff0c\u5f53\u60ac\u6d6e\u5143\u7d20\u521d\u6b21\u51fa\u73b0\u5728\u89e6\u53d1\u5143\u7d20\u65c1\u8fb9\u540e\uff0c\u89e6\u53d1\u5143\u7d20\u5728 <code>container<\/code> \u4e2d\u6eda\u52a8\u65f6\uff0c\u5047\u5982\u6ca1\u6709\u52a8\u6001\u7684\u8c03\u6574\u60ac\u6d6e\u5143\u7d20\u7684\u76f8\u5e94\u504f\u79fb\u8ddd\u79bb\uff0c\u60ac\u6d6e\u5c42\u5c31\u4f1a\u9759\u6b62\u5728\u6700\u5f00\u59cb\u51fa\u73b0\u7684\u4f4d\u7f6e\uff0c\u6ca1\u6709\u8ddf\u968f\u89e6\u53d1\u5143\u7d20\u6eda\u52a8\uff0c\u9020\u6210\u89c6\u89c9\u4e0a\u7684\u5206\u79bb\uff0c\u663e\u5f97\u7a81\u5140\u3002\uff08\u5f53\u7136\u5982\u679c\u8bbe\u8ba1\u6210\u6eda\u52a8\u65f6\u5173\u95ed\u60ac\u6d6e\u5143\u7d20\uff0c\u90a3\u81ea\u7136\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff09<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210222202031938.png\" alt=\"\"><\/p>\n<p>\u4e0a\u56fe\u4e2d\uff0c\u5f53\u6307\u9488\u60ac\u6d6e\u5728\u89e6\u53d1\u5143\u7d20 <code>trigger<\/code> \u5143\u7d20\u4e0a\u65f6\uff0c\u4f1a\u8ba1\u7b97 <code>trigger<\/code> \u5728\u89c6\u53e3\u4e2d\u7684\u4f4d\u7f6e\u548c\u6eda\u52a8\u8ddd\u79bb\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">triggerOffsetX<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">trigger<\/span><span class=\"p\">.<\/span><span class=\"nx\">getBoundingClientRect<\/span><span class=\"p\">().<\/span><span class=\"nx\">left<\/span>\n<span class=\"nx\">triggerOffsetY<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">trigger<\/span><span class=\"p\">.<\/span><span class=\"nx\">getBoundingClientRect<\/span><span class=\"p\">().<\/span><span class=\"nx\">top<\/span> <span class=\"o\">+<\/span> <span class=\"nb\">window<\/span><span class=\"p\">.<\/span><span class=\"nx\">pageYOffset<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u60ac\u6d6e\u5143\u7d20 <code>Popover<\/code> \u6839\u636e <code>triggerOffsetX<\/code>\u3001<code>triggerOffsetY<\/code> \u548c\u81ea\u8eab\u5c3a\u5bf8\u8ba1\u7b97\u76f8\u5bf9\u4e8e <code>html<\/code> \u7684\u504f\u79fb\u8ddd\u79bb\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">PopoverOffsetLeft<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">triggerOffsetX<\/span> <span class=\"o\">-<\/span> <span class=\"nx\">Popover<\/span><span class=\"p\">.<\/span><span class=\"nx\">offsetWidth<\/span> <span class=\"o\">\/<\/span> <span class=\"mi\">2<\/span>\n<span class=\"nx\">PopoverOffsetTop<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">triggerOffsetY<\/span> <span class=\"o\">-<\/span> <span class=\"nx\">Popover<\/span><span class=\"p\">.<\/span><span class=\"nx\">offsetHeight<\/span> <span class=\"o\">-<\/span> <span class=\"nx\">gap<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u70b9 <code>(PopoverOffsetLeft, PopoverOffsetTop)<\/code> \u5c31\u662f <code>Popover<\/code> \u7684\u5de6\u4e0a\u89d2\u5750\u6807\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><span class=\"lnt\">8\n<\/span><span class=\"lnt\">9\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-css\" data-lang=\"css\"><span class=\"nt\">body<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">position<\/span><span class=\"p\">:<\/span> <span class=\"kc\">relative<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"p\">.<\/span><span class=\"nc\">Popover<\/span> <span class=\"p\">{<\/span>\n\t<span class=\"k\">position<\/span><span class=\"p\">:<\/span> <span class=\"kc\">absolute<\/span><span class=\"p\">;<\/span>\n\t<span class=\"k\">left<\/span><span class=\"p\">:<\/span> <span class=\"n\">PopoverOffsetLeft<\/span><span class=\"p\">;<\/span>\n  <span class=\"k\">top<\/span><span class=\"p\">:<\/span> <span class=\"n\">PopoverOffsetTop<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5f53 <code>trigger<\/code> \u5728 <code>container<\/code> \u4e2d\u6eda\u52a8\u65f6\uff0c<code>Popover<\/code> \u8fd8\u662f\u60ac\u6d6e\u5728\u539f\u6765\u90a3\u4e2a\u4f4d\u7f6e\u9759\u6b62\uff0c\u6eda\u52a8\u5e76\u6ca1\u6709\u4f5c\u7528\u5728 <code>Popover <\/code> \u4e0a\uff08<code>Popover<\/code> \u76f8\u5bf9\u4e8e <code>body<\/code> \uff09\uff0c<code>trigger<\/code> \u548c <code>Popover<\/code> \u51fa\u73b0\u5206\u79bb\uff1a<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210222202620893.png\" alt=\"\"><\/p>\n<h3 id=\"html-\u6ea2\u51fa\">html \u6ea2\u51fa<\/h3>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-css\" data-lang=\"css\"><span class=\"o\">&lt;<\/span><span class=\"nt\">style<\/span><span class=\"o\">&gt;<\/span>\n  <span class=\"nt\">html<\/span><span class=\"o\">,<\/span> <span class=\"nt\">body<\/span><span class=\"o\">,<\/span> <span class=\"p\">.<\/span><span class=\"nc\">root<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">100<\/span><span class=\"kt\">%<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">container<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">100<\/span><span class=\"kt\">%<\/span><span class=\"p\">;<\/span>\n    <span class=\"c\">\/* overflow: auto; *\/<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"p\">.<\/span><span class=\"nc\">content<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">500<\/span><span class=\"kt\">px<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">background<\/span><span class=\"p\">:<\/span> <span class=\"n\">LightSeaGreen<\/span><span class=\"p\">;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"o\">&lt;\/<\/span><span class=\"nt\">style<\/span><span class=\"o\">&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><code>container<\/code> \u5220\u9664 <code>overflow:auto<\/code> \u540e\uff0c\u6ea2\u51fa\u7684 <code>content<\/code> \u8d85\u51fa\u4e86 <code>cotainer\u3001root\u3001body\u3001html<\/code> \u5bf9\u5e94\u7684\u89c6\u53e3\u9ad8\u5ea6\uff08<code>height: 100%<\/code>\uff09\uff0c\u6700\u7ec8\u5728 <code>html<\/code> \u5143\u7d20\u4e0a\u89e6\u53d1\u4e86\u6ea2\u51fa\u6eda\u52a8\uff0c<code>html<\/code> \u4f5c\u4e3a\u6700\u7ec8\u7684\u6eda\u52a8\u533a\u57df\uff0c\u6eda\u52a8\u533a\u57df\u9ad8\u5ea6\u8ddf <code>content<\/code> \u7684\u9ad8\u5ea6\u4e00\u81f4\uff0c\u6240\u4ee5 <code>Popover<\/code> \u76f8\u5bf9\u4e8e <code>html<\/code> \u5143\u7d20\u5728\u6eda\u52a8\u533a\u57df\u504f\u79fb\u5b9a\u4f4d\u5230 <code>trigger<\/code> \u65c1\u8fb9\u540e\uff0c<code>Popover<\/code> \u4f1a\u8ddf\u968f <code>trigger<\/code> \u5728\u6eda\u52a8\u533a\u57df\u6eda\u52a8\uff0c\u4fdd\u6301\u76f8\u5bf9\u9759\u6b62\uff1a<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210223131228600.png\" alt=\"\"><\/p>\n<p>\u6eda\u52a8\u5230\u5e95\u90e8\u540e\uff0c<code>html.scrollTop<\/code> \u6b63\u597d\u662f <code>content.offsetHeight<\/code> \u548c <code>html.offsetHeight<\/code> \u7684\u9ad8\u5ea6\u5dee 100 px\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>html<\/td>\n<td>400<\/td>\n<td>500<\/td>\n<td>100<\/td>\n<\/tr>\n<tr>\n<td>body<\/td>\n<td>400<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>root<\/td>\n<td>400<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>container<\/td>\n<td>400<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"html-\u65e0\u56fa\u5b9a\u9ad8\u5ea6\">html \u65e0\u56fa\u5b9a\u9ad8\u5ea6<\/h3>\n<p>\u5982\u679c\u628a html \u7684 <code>height: 100%<\/code> \u53bb\u6389\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-css\" data-lang=\"css\"><span class=\"nt\">html<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c\">\/* height: 100%; *\/<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"nt\">body<\/span><span class=\"o\">,<\/span> <span class=\"nt\">root<\/span><span class=\"o\">,<\/span> <span class=\"nt\">container<\/span> <span class=\"p\">{<\/span>\n\t<span class=\"k\">height<\/span><span class=\"p\">:<\/span> <span class=\"mi\">100<\/span><span class=\"kt\">%<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6b64\u65f6 <code>html<\/code> \u4e0d\u518d\u9650\u5236\u4e3a\u89c6\u53e3\u7684\u9ad8\u5ea6\uff0c <code>body, root, container { height: 100% }<\/code> \u7684\u9ad8\u5ea6\u767e\u5206\u6bd4\u6ca1\u6709\u4e86\u76f8\u5bf9\u8ba1\u7b97\u7684\u503c\uff0c\u9000\u5316\u4e3a <code>heigth: auto<\/code>\uff0c\u7531\u5b50\u5143\u7d20\u5185\u5bb9\u9ad8\u5ea6\u51b3\u5b9a\uff0c <code>content<\/code> \u7684\u56fa\u5b9a\u9ad8\u5ea6\u5c42\u5c42\u5411\u4e0a\u6491\u5f00\u4e86 <code>html<\/code> \u7684\u9ad8\u5ea6\uff0c<code>html<\/code> \u7684\u9ad8\u5ea6\u6b64\u65f6\u8ddf <code>content<\/code> \u7684\u9ad8\u5ea6\u4e00\u81f4\uff0c<code>html<\/code> \u4e0b\u6ca1\u6709\u53d1\u751f\u9ad8\u5ea6\u6ea2\u51fa\uff0c\u89c6\u53e3\u6210\u4e3a\u6eda\u52a8\u533a\u57df\uff0c\u4f46\u662f\u53ef\u4ee5\u5728 <code>html<\/code> \u4e2d\u63a7\u5236\u6eda\u52a8\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/image-20210223220031004.png\" alt=\"\"><\/p>\n<table>\n<thead>\n<tr>\n<th>\u5143\u7d20\/\u9ad8\u5ea6(px)<\/th>\n<th>offsetHeight<\/th>\n<th>scrollHeight<\/th>\n<th>scrollTop<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>html<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>100<\/td>\n<\/tr>\n<tr>\n<td>body<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>root<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>container<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>content<\/td>\n<td>500<\/td>\n<td>500<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u8bbe\u7f6e <code>html { min-height: 100%; }<\/code> \u3001<code>html { min-height: 100vh; }<\/code> \u4e5f\u662f\u540c\u6837\u7684\u6548\u679c\uff0c\u53ea\u8981 <code>html<\/code> \u7684\u9ad8\u5ea6\u4e0d\u56fa\u5b9a\uff0c\u5c31\u4f1a\u88ab\u5b50\u5143\u7d20\u9ad8\u5ea6\u6491\u5f00\u3002<\/p>\n<h3 id=\"\u7ed3\u8bba\">\u7ed3\u8bba<\/h3>\n<p>\u6240\u4ee5\u5982\u679c\u8981\u907f\u514d\u4e0a\u9762\u60ac\u6d6e\u5143\u7d20\u4e0d\u8ddf\u968f\u6eda\u52a8\u7684\u95ee\u9898\uff0c\u4e0d\u80fd\u5728\u67d0\u4e2a\u5bb9\u5668\u5143\u7d20\u4e0a\u8bbe\u7f6e <code>overflow: auto<\/code>\u3001<code>overflow: hidden<\/code> \uff0c\u9700\u8981\u8ba9\u5b50\u5143\u7d20\u6ea2\u51fa\u5c4f\u5e55\u9ad8\u5ea6\u7684\u90e8\u5206\u5411\u4e0a\u4f20\u64ad\uff0c\u6491\u5f00 <code>html<\/code>\u3001<code>body<\/code> \u7684\u9ad8\u5ea6\uff0c\u8ba9 <code>html<\/code>\u3001<code>body<\/code> \u7684\u6eda\u52a8\u533a\u57df\u9ad8\u5ea6\u8ddf <code>content<\/code>\uff08<strong>\u957f\u5143\u7d20<\/strong>\uff09\u9ad8\u5ea6\u4e00\u81f4\uff0c\u5373\u60ac\u6d6e\u5143\u7d20\u8ddf\u89e6\u53d1\u5143\u7d20\u7684\u6eda\u52a8\u80cc\u666f\u91cd\u53e0\uff0c\u4fdd\u8bc1\u540c\u6b65\u6eda\u52a8\u3002<\/p>\n<p>\u5176\u5b9e\u8ba9\u60ac\u6d6e\u5143\u7d20\u8ddf\u968f\u6eda\u52a8\u8fd8\u6709\u53e6\u4e00\u79cd\u601d\u8def\uff0c <code>html<\/code>\u3001<code>body<\/code> \u4f5c\u4e3a\u60ac\u6d6e\u5143\u7d20\u5b9a\u4f4d\u7684\u53c2\u8003\u5143\u7d20\u53ea\u662f\u901a\u7528\u65b9\u6848\uff0c\u60ac\u6d6e\u5143\u7d20\u4e5f\u53ef\u4ee5\u76f4\u63a5\u6302\u8f7d\u5230\u957f\u5143\u7d20\u4e0b\uff0c\u8ddf\u89e6\u53d1\u5143\u7d20\u5904\u4e8e\u540c\u4e00\u6eda\u52a8\u533a\u57df\uff0c\u81ea\u7136\u5c31\u80fd\u5728\u6eda\u52a8\u65f6\u4fdd\u6301\u76f8\u5bf9\u9759\u6b62\u3002\u901a\u5e38\u7ec4\u4ef6\u5e93\u4e2d\u7684\u60ac\u6d6e\u5c42\u90fd\u4f1a\u63d0\u4f9b\u81ea\u5b9a\u4e49\u6302\u8f7d\u70b9\u7684 API\uff0c\u5c31\u662f\u7528\u6765\u7ed5\u8fc7 <code>body<\/code> \u6ca1\u6491\u5f00\u6216\u4e0d\u6eda\u52a8\u7684\u5e03\u5c40\uff0c\u89c1 <a href=\"https:\/\/ant-design.gitee.io\/components\/select-cn\/#API\">Ant Design Select \u7ec4\u4ef6 <code>getPopupContainer()<\/code> prop<\/a>\u3002<\/p>\n<h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2>\n<p>\u672c\u6587\u91cd\u6e29\u4e86 CSS <code>overflow<\/code> \u7684\u57fa\u7840\u7279\u6027\uff0c\u548c\u4e0e\u5176\u76f8\u5173\u8054\u7684\u5143\u7d20\u9ad8\u5ea6\u5c5e\u6027\uff0c\u5e76\u901a\u8fc7 demo \u89c2\u6d4b <code>overflow<\/code> \u7684\u5404\u4e2a\u503c\u662f\u5982\u4f55\u5f71\u54cd\u5143\u7d20\u9ad8\u5ea6\u3001\u9875\u9762\u5e03\u5c40\u7684\uff0c\u63a2\u7d22\u5982\u4f55\u89e3\u51b3\u60ac\u6d6e\u5143\u7d20\u6eda\u52a8\u5206\u79bb\u7684\u95ee\u9898\u3002\u4ee5\u540e\u5728\u9047\u5230\u6eda\u52a8\u76f8\u5173\u95ee\u9898\u65f6\uff0c\u53ef\u4ee5\u5229\u7528 <code>overflow<\/code>\u3001<code>scrollTop<\/code> \u5b9a\u4f4d\u6eda\u52a8\u533a\u57df\uff0c\u5f04\u6e05\u695a\u662f\u54ea\u4e2a\u5b50\u5143\u7d20\u5728\u7236\u5143\u7d20\u91cc\u6ea2\u51fa\u4e86\u3002<\/p>\n<p>CSS \u771f\u662f\u8d8a\u5b66\u8d8a\u7384\uff0c\u5f88\u591a\u60c5\u51b5\u90fd\u9700\u8981\u4f9d\u9760\u5177\u4f53\u8868\u73b0\u548c\u6570\u636e\u6765\u63a8\u65ad\u6d4f\u89c8\u5668\u7684\u9875\u9762\u6e32\u67d3\u673a\u5236\uff0c\u7384\u5b66\u8fd8\u5f97\u9760\u5b9e\u9a8c\u89c2\u6d4b\ud83d\udc41<\/p>\n<h2 id=\"\u53c2\u8003\">\u53c2\u8003<\/h2>\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/overflow\">MDN CSS overflow<\/a><\/p>\n<p><a href=\"https:\/\/css-tricks.com\/the-css-overflow-property\/\">The CSS Overflow Property<\/a><\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/previous-versions\/\/hh781509(v=vs.85)\">Measuring Element Dimension and Location with CSSOM in Windows Internet Explorer 9<\/a><\/p>"},{"title":"\u8bbe\u8ba1\u4e00\u5bf9\u901a\u7528\u7684\u6d88\u606f\u63d0\u793a\u7ec4\u4ef6 \u2014\u2014 Alert & Toast","link":"https:\/\/jancat.github.io\/post\/2020\/design-a-pair-of-general-message-prompt-components-alert-and-toast\/","pubDate":"Sat, 26 Dec 2020 22:02:07 +0800","guid":"https:\/\/jancat.github.io\/post\/2020\/design-a-pair-of-general-message-prompt-components-alert-and-toast\/","description":"<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221536.png\" alt=\"\"><\/p>\n<p>\u5728\u6d4f\u89c8\u5668\u9875\u9762\u4e2d\uff0c\u901a\u7528\u7684\u6d88\u606f\u63d0\u793a\u7ec4\u4ef6\u4e00\u822c\u53ef\u4ee5\u5206\u4e3a<strong>\u9759\u6001\u5c40\u90e8\u63d0\u793a<\/strong>\u548c<strong>\u52a8\u6001\u5168\u5c40\u63d0\u793a<\/strong>\uff0c\u7528\u4e8e\u53cd\u9988\u7528\u6237\u9700\u8981\u5173\u6ce8\u7684\u4fe1\u606f\uff0c\u4f7f\u7528\u9891\u7387\u8f83\u9ad8\u3002<\/p>\n<p>\u867d\u7136\u8fd9\u4e24\u79cd\u63d0\u793a\u4ece\u89c6\u89c9\u4ea4\u4e92\u4e0a\u6765\u770b\u6bd4\u8f83\u76f8\u4f3c\uff0c\u4f46\u4f7f\u7528\u573a\u666f\u4e0d\u540c\uff0c\u7ec4\u4ef6\u5bf9\u5916\u66b4\u9732\u7684\u63a5\u53e3\u4e5f\u6709\u4e00\u70b9\u533a\u522b\uff0c\u6240\u4ee5\u4e00\u822c\u62c6\u5206\u6210\u4e24\u4e2a UI \u7ec4\u4ef6\u63d0\u4f9b\u7ed9\u4e1a\u52a1\u65b9\u4f7f\u7528\u3002<\/p>\n<p>\u4ee3\u7801\u672a\u52a8\uff0c\u8bbe\u8ba1\u5148\u884c\uff0c\u5148\u8003\u8651\u63a5\u53e3\uff0c\u518d\u8003\u8651\u5b9e\u73b0\u3002\u672c\u6587\u4ecb\u7ecd\u5982\u4f55\u8bbe\u8ba1\u8fd9\u4e24\u4e2a\u7ec4\u4ef6\uff08\u5c55\u793a\u3001\u4ea4\u4e92\u3001API\u3001\u5b9e\u73b0\u601d\u8def\uff09\uff0c\u6ee1\u8db3\u4e1a\u52a1\u65b9\u7684\u5b9a\u5236\u5316\u548c\u7ec4\u4ef6\u7684\u901a\u7528\u5316\uff0c\u63d0\u4f9b\u7b80\u5355\u6613\u7528\u3001\u89c6\u89c9\u4ea4\u4e92\u53cb\u597d\u7684\u6d88\u606f\u63d0\u793a\u7ec4\u4ef6\u3002<\/p>\n<p>\u4ee5\u4e0b\u7684\u8bbe\u8ba1\u601d\u8def\u6574\u7406\u603b\u7ed3\u81ea People Design\u3001 Ant Design \u3001Material-UI \u7684\u6d88\u606f\u63d0\u793a\u7ec4\u4ef6 \uff0c\u4e3b\u8981\u9488\u5bf9 PC \u7aef\u8bbe\u8ba1\u5c55\u793a\u548c\u4ea4\u4e92\uff0c\u4f7f\u7528 React \u8bed\u6cd5 \uff1b\u672c\u6587\u4e3b\u8981\u5173\u6ce8\u7ec4\u4ef6\u57fa\u7840\u8bbe\u8ba1\u601d\u8def\uff0c\u4e0d\u6d89\u53ca\uff1a\u5177\u4f53\u4ee3\u7801\u5b9e\u73b0\u3001\u65e0\u969c\u788d\u8bbe\u8ba1 WAI-ARIA\u3001\u4e3b\u9898\u5207\u6362\u3001\u79fb\u52a8\u7aef\u9002\u914d\u7b49\u3002<\/p>\n<p>Alert &amp; Toast \u2193\u2193<\/p>\n<h2 id=\"alert-\u8b66\u544a\u63d0\u793a\">Alert \u8b66\u544a\u63d0\u793a<\/h2>\n<p>\u9759\u6001\u5c40\u90e8\u63d0\u793a\u7ec4\u4ef6\u5728 Antd \u548c Material-UI \u4e2d\u547d\u540d\u4e3a <strong>Alert \u8b66\u544a\u63d0\u793a<\/strong><\/p>\n<h3 id=\"\u4f7f\u7528\u573a\u666f\">\u4f7f\u7528\u573a\u666f<\/h3>\n<p>\u9875\u9762\u5c40\u90e8\u5c55\u793a\u4e00\u6bb5\u7b80\u77ed\u4e14\u91cd\u8981\u7684\u4fe1\u606f\uff0c\u5728\u4e0d\u5f71\u54cd\u7528\u6237\u64cd\u4f5c\u7684\u540c\u65f6\u80fd\u591f\u5438\u5f15\u7528\u6237\u7684\u6ce8\u610f\u529b\u3002<\/p>\n<h3 id=\"\u5c55\u793a\u4ea4\u4e92\">\u5c55\u793a\u4ea4\u4e92<\/h3>\n<p>\u6d88\u606f\u6846\u5bbd\u5ea6\u9ed8\u8ba4\u6c34\u5e73\u6491\u6ee1\u5f53\u524d\u5bb9\u5668\uff0c\u4ee5\u975e\u6d6e\u5c42\u7684\u9759\u6001\u5c55\u73b0\u5f62\u5f0f\uff0c\u59cb\u7ec8\u5c55\u73b0\uff0c\u4e0d\u4f1a\u81ea\u52a8\u6d88\u5931\uff0c\u7528\u6237\u53ef\u4ee5\u70b9\u51fb\u5173\u95ed\uff0c\u53ef\u4ee5\u63d0\u4f9b\u81ea\u5b9a\u4e49\u7684\u64cd\u4f5c\u6309\u94ae\u3002<\/p>\n<h3 id=\"\u6807\u9898\u548c\u63cf\u8ff0\">\u6807\u9898\u548c\u63cf\u8ff0<\/h3>\n<p>Alert \u63d0\u793a\u53ef\u4ee5\u6307\u5b9a\u6807\u9898\uff0c\u8868\u793a\u63d0\u793a\u7684\u7c7b\u578b\u6216\u4e3b\u9898<\/p>\n<p>\u957f\u6587\u672c\u63d0\u793a\u5efa\u8bae\u589e\u52a0\u6807\u9898\uff0c\u7528\u6237\u53ef\u5feb\u901f\u7406\u89e3\u4e3b\u8981\u5185\u5bb9\uff0c\u5185\u5bb9\u5efa\u8bae\u4e0d\u8d85\u8fc7 4 \u884c\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221001.png\" alt=\"\"><\/p>\n<p><em>Material-UI Alert \u5e26\u6807\u9898\u548c\u5185\u5bb9<\/em><\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221028.png\" alt=\"\"><\/p>\n<p><em>AntD Alert \u5e26\u6807\u9898\u548c\u5185\u5bb9<\/em><\/p>\n<h4 id=\"api-\u8bbe\u8ba1\">API \u8bbe\u8ba1<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u53c2\u6570<\/th>\n<th>\u8bf4\u660e<\/th>\n<th>\u7c7b\u578b<\/th>\n<th>\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>message<\/td>\n<td>\u8b66\u544a\u63d0\u793a\u5185\u5bb9\uff0c\u4e00\u822c\u662f\u6587\u672c<\/td>\n<td>ReactNode<\/td>\n<td>-<\/td>\n<\/tr>\n<tr>\n<td>title<\/td>\n<td>\u5728\u5185\u5bb9\u4e0a\u65b9\u5c55\u793a\u7684\u6d88\u606f\u6807\u9898<\/td>\n<td>ReactNode<\/td>\n<td>-<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-jsx\" data-lang=\"jsx\"><span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">title<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;\u6807\u9898&#34;<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;\u63d0\u793a\u5185\u5bb9&#34;<\/span> <span class=\"p\">\/&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"\u63d0\u793a\u7c7b\u578b\">\u63d0\u793a\u7c7b\u578b<\/h3>\n<p>Alert \u6309\u7167\u529f\u80fd\u9ed8\u8ba4\u63d0\u4f9b\u56db\u79cd\u7c7b\u578b\u7684\u63d0\u793a\uff0c\u5206\u522b\u662f\uff1a<\/p>\n<ul>\n<li><strong>\u666e\u901a\u63d0\u793a info<\/strong>\uff1a\u7528\u4e8e\u5c55\u793a\u80cc\u666f\u6761\u4ef6\u3001\u653f\u7b56\u4fe1\u606f\u3001\u89c4\u8303\u8981\u6c42\u3001\u5f53\u524d\u72b6\u6001\u7b49\u5ba2\u89c2\u5185\u5bb9\uff1b<\/li>\n<li><strong>\u6210\u529f\u63d0\u793a success<\/strong>\uff1a\u7528\u4e8e\u5c55\u793a\u5df2\u5b8c\u6210\u64cd\u4f5c\u7684\u6210\u529f\u72b6\u6001\uff1b<\/li>\n<li><strong>\u8b66\u544a\u63d0\u793a warning<\/strong>\uff1a\u7528\u4e8e\u5c55\u793a\u53ef\u80fd\u4f1a\u5bfc\u81f4\u67d0\u79cd\u540e\u679c\u7684\u8b66\u793a\u6027\u6587\u672c\uff1b<\/li>\n<li><strong>\u9519\u8bef\u63d0\u793a error<\/strong>\uff1a\u7528\u4e8e\u5c55\u793a\u5f53\u524d\u64cd\u4f5c\u6216\u8005\u6574\u4f53\u72b6\u6001\u6709\u9519\u8bef\uff0c\u63d0\u793a\u7528\u6237\u4fee\u6b63\u6216\u5c55\u793a\u9519\u8bef\u76f8\u5173\u4fe1\u606f\u3002<\/li>\n<\/ul>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221039.png\" alt=\"\"><\/p>\n<p><em>AntD Alert \u56db\u79cd\u63d0\u793a\u7c7b\u578b<\/em><\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221048.png\" alt=\"\"><\/p>\n<p><em>Material-UI Alert \u56db\u79cd\u63d0\u793a\u7c7b\u578b<\/em><\/p>\n<p>\u6bcf\u79cd\u63d0\u793a\u7c7b\u578b\u90fd\u63d0\u4f9b\u5bf9\u5e94\u7684\u56fe\u6807\u5c55\u793a\u5728\u6d88\u606f\u5f00\u5934\uff0c\u5408\u9002\u7684\u56fe\u6807\u8ba9\u4fe1\u606f\u7c7b\u578b\u66f4\u52a0\u9192\u76ee\uff0c\u4e0d\u5e26\u56fe\u6807\u9002\u5408\u5355\u8c03\u7b80\u5355\u7684\u63d0\u793a\u3002<\/p>\n<h4 id=\"api-\u8bbe\u8ba1-1\">API \u8bbe\u8ba1<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u53c2\u6570<\/th>\n<th>\u8bf4\u660e<\/th>\n<th>\u7c7b\u578b<\/th>\n<th>\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>type<\/td>\n<td>\u63d0\u793a\u7c7b\u578b\uff0c\u5171\u6709\u56db\u79cd\u9009\u62e9 <code>success<\/code>\u3001<code>info<\/code>\u3001<code>warning<\/code>\u3001<code>error<\/code><\/td>\n<td>string<\/td>\n<td><code>info<\/code><\/td>\n<\/tr>\n<tr>\n<td>icon<\/td>\n<td>\u8f85\u52a9\u56fe\u6807\uff0c\u53ef\u4ee5\u6307\u5b9a <code>false<\/code> \u4e0d\u5c55\u793a\u56fe\u6807\uff0c\u6216\u8005\u63d0\u4f9b\u81ea\u5b9a\u4e49\u56fe\u6807<\/td>\n<td>ReactNode | boolean<\/td>\n<td>type \u5bf9\u5e94\u7684 icon<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-jsx\" data-lang=\"jsx\"><span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;info tips&#34;<\/span> <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;info&#34;<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;success tips&#34;<\/span> <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;success&#34;<\/span> <span class=\"na\">icon<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"kc\">false<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;warning tips&#34;<\/span> <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;warning&#34;<\/span> <span class=\"na\">icon<\/span><span class=\"o\">=<\/span><span class=\"p\">{&lt;<\/span><span class=\"nt\">CustomIcon<\/span> <span class=\"p\">\/&gt;}<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;error tips&#34;<\/span> <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;error&#34;<\/span> <span class=\"p\">\/&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"\u53d8\u4f53\">\u53d8\u4f53<\/h3>\n<p>\u63d0\u793a\u6846\u6709\u63cf\u8fb9\uff08outlined\uff09\u548c\u586b\u5145\uff08filled\uff09\u8fd9\u4e24\u79cd\u53d8\u4f53\u53ef\u4ee5\u4f7f\u7528\uff0c\u4ee5\u4fbf\u5339\u914d\u4e0d\u540c\u7684\u8bbe\u8ba1\u98ce\u683c\u3002<\/p>\n<p>\u6807\u51c6\uff08\u9ed8\u8ba4\uff09\u662f\u6d45\u8272\u586b\u5145\u65e0\u8fb9\u6846\uff0c\u586b\u5145\uff08filled\uff09\u662f\u6df1\u8272\u586b\u5145\uff0c\u63cf\u8fb9\uff08outlined\uff09\u53ea\u6709\u8fb9\u6846\u65e0\u586b\u5145\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221058.png\" alt=\"\"><\/p>\n<p><em>Material-UI Alert \u53d8\u4f53\u793a\u4f8b<\/em><\/p>\n<h4 id=\"api-\u8bbe\u8ba1-2\">API \u8bbe\u8ba1<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u53c2\u6570<\/th>\n<th>\u8bf4\u660e<\/th>\n<th>\u7c7b\u578b<\/th>\n<th>\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>variant<\/td>\n<td>\u53d8\u4f53\u7c7b\u578b\uff0c\u5171\u6709\u4e09\u79cd\u9009\u62e9 <code>standard<\/code>\u3001<code>filled<\/code>\u3001<code>outlined<\/code><\/td>\n<td>string<\/td>\n<td><code>standard<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-jsx\" data-lang=\"jsx\"><span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;info tips&#34;<\/span> <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;info&#34;<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;success tips&#34;<\/span> <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;success&#34;<\/span> <span class=\"na\">variant<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;filled&#34;<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;warning tips&#34;<\/span> <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;warning&#34;<\/span> <span class=\"na\">variant<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;outlined&#34;<\/span> <span class=\"p\">\/&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"\u53ef\u5173\u95ed\">\u53ef\u5173\u95ed<\/h3>\n<p>\u5f53\u7528\u6237\u63a5\u6536\u5230 Alert \u63d0\u4f9b\u7684\u4fe1\u606f\u540e\uff0c\u53ef\u80fd\u4e0d\u5e0c\u671b\u518d\u88ab Alert \u5438\u5f15\u6ce8\u610f\u529b\uff0c\u5f71\u54cd\u5bf9\u5176\u5b83\u4fe1\u606f\u7684\u5904\u7406\uff1b\u6b64\u65f6\u53ef\u4ee5\u914d\u7f6e\u5173\u95ed\u6309\u94ae\uff0c\u5141\u8bb8\u7528\u6237\u4e3b\u52a8\u5173\u95ed Alert\u3002<\/p>\n<p>\u5173\u95ed\u540e\u6dfb\u52a0 leave \u7684\u8fc7\u6e21\u52a8\u6548\uff0c\u5e73\u6ed1\u81ea\u7136\u5730\u6536\u8d77 Alert\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221111.png\" alt=\"\"><\/p>\n<p><em>AntD Alert \u81ea\u5b9a\u4e49\u5173\u95ed\u793a\u4f8b<\/em><\/p>\n<h4 id=\"api-\u8bbe\u8ba1-3\">API \u8bbe\u8ba1<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u53c2\u6570<\/th>\n<th>\u8bf4\u660e<\/th>\n<th>\u7c7b\u578b<\/th>\n<th>\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>closeText<\/td>\n<td>\u81ea\u5b9a\u4e49\u5173\u95ed\u6309\u94ae\uff0c\u66ff\u6362\u9ed8\u8ba4\u7684 x \u56fe\u6807<\/td>\n<td>ReactNode<\/td>\n<td><code>-<\/code><\/td>\n<\/tr>\n<tr>\n<td>closable<\/td>\n<td>\u9ed8\u8ba4\u4e0d\u53ef\u5173\u95ed<\/td>\n<td>boolean<\/td>\n<td>false<\/td>\n<\/tr>\n<tr>\n<td>afterClose<\/td>\n<td>\u5173\u95ed\u540e\u89e6\u53d1\u7684\u56de\u8c03\u51fd\u6570<\/td>\n<td>() =&gt; void<\/td>\n<td>-<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-jsx\" data-lang=\"jsx\"><span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span> <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;info tips&#34;<\/span> <span class=\"na\">closable<\/span> <span class=\"na\">closeText<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;\u5173\u95ed&#34;<\/span> <span class=\"na\">afterClose<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;closed&#39;<\/span><span class=\"p\">)}<\/span> <span class=\"p\">\/&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"\u64cd\u4f5c\">\u64cd\u4f5c<\/h3>\n<p>\u63d0\u793a\u4e2d\u53ef\u4ee5\u914d\u7f6e\u64cd\u4f5c\u6309\u94ae\uff0c\u5728\u5c3e\u90e8\u5c55\u793a\uff08\u5173\u95ed\u6309\u94ae\u4e4b\u524d\uff09\u3002\u6587\u672c\u6d88\u606f\u4e0d\u8d85\u8fc7\u53f3\u4fa7\u64cd\u4f5c\u6309\u94ae\u533a\u57df\uff0c\u95f4\u9694\u4e00\u5b9a\u95f4\u8ddd\u6362\u884c\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221121.png\" alt=\"\"><\/p>\n<p><em>AntD Alert \u64cd\u4f5c\u793a\u4f8b<\/em><\/p>\n<p>\u6d88\u606f\u5185\u5bb9\u4e2d\u4e5f\u53ef\u4ee5\u81ea\u5b9a\u4e49\u6587\u672c\u94fe\u63a5\uff0c\u70b9\u51fb\u4f1a\u8df3\u8f6c\u5230\u5176\u5b83\u9875\u9762\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221131.png\" alt=\"\"><\/p>\n<p><em>People Design \u5e38\u9a7b\u63d0\u793a\u64cd\u4f5c\u793a\u4f8b<\/em><\/p>\n<h4 id=\"api-\u8bbe\u8ba1-4\">API \u8bbe\u8ba1<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u53c2\u6570<\/th>\n<th>\u8bf4\u660e<\/th>\n<th>\u7c7b\u578b<\/th>\n<th>\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>action<\/td>\n<td>\u81ea\u5b9a\u4e49\u64cd\u4f5c\u9879<\/td>\n<td>ReactNode<\/td>\n<td><code>-<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-jsx\" data-lang=\"jsx\"><span class=\"p\">&lt;<\/span><span class=\"nt\">Alert<\/span>\n  <span class=\"na\">message<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;Success Tips&#34;<\/span>\n  <span class=\"na\">type<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;success&#34;<\/span>\n  <span class=\"na\">action<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span>\n    <span class=\"p\">&lt;<\/span><span class=\"nt\">button<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Action clicked.&#39;<\/span><span class=\"p\">)}&gt;<\/span><span class=\"nx\">UNDO<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">button<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">\/&gt;<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h2 id=\"toast-\u5168\u5c40\u63d0\u793a\">Toast \u5168\u5c40\u63d0\u793a<\/h2>\n<blockquote>\n<p>\u6709\u4e9b\u7ec4\u4ef6\u5e93\u547d\u540d\u4e3a Message\u3001Snackbar \u7b49<\/p>\n<\/blockquote>\n<p>\u5168\u5c40\u63d0\u793a\u662f\u64cd\u4f5c\u540e\u7684\u8f7b\u91cf\u7ea7\u77ed\u65f6\u53cd\u9988\u63d0\u793a\uff0c\u4e0d\u4f1a\u6253\u65ad\u7528\u6237\u64cd\u4f5c\u3002<\/p>\n<h3 id=\"\u4f7f\u7528\u573a\u666f-1\">\u4f7f\u7528\u573a\u666f<\/h3>\n<p>\u7528\u4e8e\u5c55\u793a\u64cd\u4f5c\u540e\u7cfb\u7edf\u5bf9\u8be5\u884c\u4e3a\u4f5c\u51fa\u7684\u53cd\u9988\uff0c\u5982\u6210\u529f\u3001\u8b66\u793a\u3001\u9519\u8bef\u3001\u63d0\u793a\u4fe1\u606f\u7b49\u3002<\/p>\n<h3 id=\"\u5c55\u793a\u4ea4\u4e92-1\">\u5c55\u793a\u4ea4\u4e92<\/h3>\n<p>\u4f4d\u4e8e\u9875\u9762\u9876\u90e8\u4e2d\u592e\uff0c\u8ddd\u79bb\u9876\u90e8\u6709\u56fa\u5b9a\u95f4\u8ddd\u3002\u6d88\u606f\u6846\u5bbd\u5ea6\u968f\u5185\u5bb9\u81ea\u9002\u5e94\uff0c\u8d85\u8fc7\u6700\u5927\u5bbd\u5ea6\u540e\u6587\u672c\u6362\u884c\u3002\u4e0d\u968f\u9875\u9762\u6eda\u52a8\uff0c\u6709\u6d6e\u5c42\u9634\u5f71\u6548\u679c\u3002<\/p>\n<p>\u5c55\u793a\u4e00\u6bb5\u65f6\u95f4\u540e\u81ea\u52a8\u6d88\u606f\uff08\u53ef\u4ee5\u8bbe\u7f6e\u4e0d\u81ea\u52a8\u5173\u95ed\uff09\uff0c\u5bf9\u5185\u5bb9\u5e72\u6270\u964d\u5230\u6700\u4f4e\u3002<\/p>\n<p>\u5f53\u4e0d\u540c\u64cd\u4f5c\u89e6\u53d1\u4e86\u591a\u6761\u5168\u5c40\u63d0\u793a\uff0c\u6309\u7167\u65f6\u95f4\u5148\u540e\u987a\u5e8f\u5728\u9875\u9762\u4e0a\u65b9\u4e2d\u592e\u4f9d\u6b21\u5806\u53e0\u51fa\u73b0\uff0c\u5c06\u672a\u6d88\u5931\u63d0\u793a\u63a8\u81f3\u4e0b\u65b9\u3002<\/p>\n<p>\u6d88\u606f\u51fa\u73b0\uff08\u4ece\u4e0a\u81f3\u4e0b\u6389\u843d\u6216\u4ece\u5c0f\u653e\u5927\uff09\u548c\u6d88\u5931\uff08\u76f8\u53cd\u52a8\u4f5c\uff09\u90fd\u4f1a\u6709\u8fc7\u6e21\u3002<\/p>\n<p>\u5f53\u6307\u9488\u60ac\u6d6e\u5728 Toast \u4e0a\u65f6\uff0c\u8ba4\u4e3a\u7528\u6237\u6b64\u65f6\u6b63\u5728\u5173\u6ce8\u6b64\u63d0\u793a\uff0c\u6240\u4ee5\u6e05\u9664 Toast \u81ea\u52a8\u5173\u95ed\u7684\u5b9a\u65f6\u5668\uff0c\u907f\u514d Toast \u7a81\u7136\u5728\u7528\u6237\u5173\u6ce8\u7126\u70b9\u4e2d\u6d88\u5931\uff1b\u5f53\u6307\u9488\u79bb\u5f00 Toast \u540e\uff0c\u91cd\u65b0\u521b\u5efa Toast \u7684\u5173\u95ed\u5b9a\u65f6\u5668\u3002<\/p>\n<h3 id=\"\u548c-alert-\u7684\u5bf9\u6bd4\">\u548c Alert \u7684\u5bf9\u6bd4<\/h3>\n<ul>\n<li>Alert \u4f5c\u4e3a\u5c40\u90e8\u7ec4\u4ef6\u5d4c\u5165\uff1bToast \u9875\u9762\u6700\u4e0a\u5c42\u6d6e\u52a8\u5c55\u793a\uff0c\u6697\u793a\u5168\u5c40\u6027\uff1b<\/li>\n<li>Alert \u8ddf\u968f\u5bb9\u5668\u4e00\u8d77\u9759\u6001\u51fa\u73b0\uff1b Toast \u5728\u67d0\u4e2a\u64cd\u4f5c\u540e\u52a8\u6001\u6d6e\u73b0\uff1b<\/li>\n<li>Alert \u9ed8\u8ba4\u5e38\u9a7b\uff1bToast \u51fa\u73b0\u540e\u9ed8\u8ba4\u81ea\u52a8\u6d88\u5931\uff1b<\/li>\n<li>Alert \u5728\u6a21\u677f\u4e2d\u58f0\u660e\u5f0f\u5f15\u7528\uff1bToast \u5728\u5168\u5c40 JavaScript \u4f5c\u7528\u57df\u5185\u547d\u4ee4\u5f0f\u9759\u6001\u65b9\u6cd5\u8c03\u7528\uff0c\u53ef\u4ee5\u770b\u4f5c\u662f\u5de5\u5177\u65b9\u6cd5\uff0c\u5728\u4e8b\u4ef6\u4e2d\u89e6\u53d1\uff1b<\/li>\n<li>Alert \u6bcf\u4e2a\u5b9e\u4f8b\u72ec\u7acb\uff0c\u914d\u7f6e\u4e0d\u5171\u4eab\uff1bToast \u5b9e\u4f8b\u95f4\u5171\u4eab\u5168\u5c40\u914d\u7f6e\uff0c\u53ef\u4ee5\u7edf\u4e00\u7ba1\u7406\uff0c\u914d\u7f6e\u9ed8\u8ba4\u7684\u6837\u5f0f\u548c\u884c\u4e3a\uff1b<\/li>\n<li>Alert \u63d0\u4f9b action prop\uff1bToast \u4e3a\u8f7b\u4ea4\u4e92\uff0c\u4e0d\u63d0\u4f9b\u989d\u5916\u64cd\u4f5c\uff0c\u4f46\u53ef\u4ee5\u5728 content \u4e2d\u81ea\u884c\u5d4c\u5165\uff08\u57fa\u672c\u7ea6\u675f\uff0c\u7075\u6d3b\u5b9a\u5236\uff09\uff1b<\/li>\n<li>Alert \u63d0\u4f9b title prop\uff1bToast \u4e3a\u8f7b\u63d0\u793a\uff0c\u4e00\u822c\u4e0d\u9700\u8981\u6807\u9898\uff0c\u4f46\u540c\u6837\u53ef\u4ee5\u5728 content \u4e2d\u81ea\u884c\u5d4c\u5165\u3002<\/li>\n<\/ul>\n<h3 id=\"\u63d0\u793a\u7c7b\u578b-1\">\u63d0\u793a\u7c7b\u578b<\/h3>\n<p>Toast \u9664\u4e86 Alert \u7684\u56db\u79cd\u63d0\u793a\u7c7b\u578b\u5916\uff0c\u8fd8\u6709\u4e00\u79cd loading \u7c7b\u578b\uff1a<\/p>\n<ul>\n<li><strong>\u52a0\u8f7d\u4e2d loading<\/strong>\uff1a\u7528\u4e8e\u5c55\u793a\u5f53\u524d\u64cd\u4f5c\u6b63\u5728\u5904\u7406\u4e2d\u6216\u8005\u5185\u5bb9\u6b63\u5728\u52a0\u8f7d\u4e2d<\/li>\n<\/ul>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/images\/20201226221143.png\" alt=\"\"><\/p>\n<p><em>AntD message \u793a\u4f8b<\/em><\/p>\n<h3 id=\"\u53d8\u4f53-1\">\u53d8\u4f53<\/h3>\n<blockquote>\n<p>\u540c Alert<\/p>\n<\/blockquote>\n<h3 id=\"\u9759\u6001\u65b9\u6cd5-api\">\u9759\u6001\u65b9\u6cd5 API<\/h3>\n<blockquote>\n<p>API \u57fa\u672c\u53c2\u7167 AntD message<\/p>\n<\/blockquote>\n<p>Toast \u4f5c\u4e3a\u7279\u6b8a\u7684\u5de5\u5177\u7ec4\u4ef6\uff0c\u63d0\u4f9b\u6bcf\u4e2a\u63d0\u793a\u7c7b\u578b\u7684\u9759\u6001\u65b9\u6cd5\u8c03\u7528\uff1a<\/p>\n<ul>\n<li><code>Toast.success(content, [duration], onClose)<\/code><\/li>\n<li><code>Toast.error(content, [duration], onClose)<\/code><\/li>\n<li><code>Toast.info(content, [duration], onClose)<\/code><\/li>\n<li><code>Toast.warning(content, [duration], onClose)<\/code><\/li>\n<li><code>Toast.loading(content, [duration], onClose)<\/code><\/li>\n<\/ul>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">\u53c2\u6570<\/th>\n<th style=\"text-align:left\">\u8bf4\u660e<\/th>\n<th style=\"text-align:left\">\u7c7b\u578b<\/th>\n<th style=\"text-align:left\">\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">content<\/td>\n<td style=\"text-align:left\">\u63d0\u793a\u5185\u5bb9<\/td>\n<td style=\"text-align:left\">ReactNode | config<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">duration<\/td>\n<td style=\"text-align:left\">\u81ea\u52a8\u5173\u95ed\u7684\u5ef6\u65f6\uff0c\u5355\u4f4d\u79d2\u3002\u8bbe\u4e3a 0 \u65f6\u4e0d\u81ea\u52a8\u5173\u95ed<\/td>\n<td style=\"text-align:left\">number<\/td>\n<td style=\"text-align:left\">3<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">onClose<\/td>\n<td style=\"text-align:left\">\u5173\u95ed\u65f6\u89e6\u53d1\u7684\u56de\u8c03\u51fd\u6570<\/td>\n<td style=\"text-align:left\">function<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4 id=\"\u8fd4\u56de-promise\">\u8fd4\u56de promise<\/h4>\n<p>\u9759\u6001\u65b9\u6cd5\u8c03\u7528\u540e\u8fd4\u56de promise\uff0c\u53ef\u4ee5\u4f7f\u7528 <code>.then()<\/code>\u3001 <code>await<\/code> \u8bed\u6cd5\uff0c\u4ee5\u540c\u6b65\u7684\u5199\u6cd5\u5728\u4e4b\u540e\u6267\u884c Toast \u5173\u95ed\u540e\u7684\u903b\u8f91\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\">Toast[level](content, [duration]).then(afterClose)\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">await<\/span> <span class=\"nx\">Toast<\/span><span class=\"p\">[<\/span><span class=\"nx\">level<\/span><span class=\"p\">](<\/span><span class=\"nx\">content<\/span><span class=\"p\">,<\/span> <span class=\"p\">[<\/span><span class=\"nx\">duration<\/span><span class=\"p\">])<\/span>\n<span class=\"nx\">afterClose<\/span><span class=\"p\">()<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"\u5b9e\u73b0\u601d\u8def\">\u5b9e\u73b0\u601d\u8def<\/h4>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kd\">function<\/span> <span class=\"nx\">openToast<\/span><span class=\"p\">(<\/span><span class=\"nx\">configs<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n\t<span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Promise<\/span><span class=\"p\">(<\/span><span class=\"nx\">resolve<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">new<\/span> <span class=\"nx\">Toast<\/span><span class=\"p\">({<\/span> <span class=\"p\">...<\/span><span class=\"nx\">configs<\/span><span class=\"p\">,<\/span> <span class=\"nx\">onClose<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">resolve<\/span><span class=\"p\">(<\/span><span class=\"kc\">true<\/span><span class=\"p\">)<\/span>\n      <span class=\"nx\">configs<\/span><span class=\"p\">.<\/span><span class=\"nx\">onClose<\/span><span class=\"o\">?<\/span><span class=\"p\">.()<\/span>\n    <span class=\"p\">}}})<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">Toast<\/span><span class=\"p\">()<\/span> <span class=\"p\">{}<\/span>\n\n<span class=\"p\">[<\/span><span class=\"s1\">&#39;success&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;error&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;info&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;warning&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;loading&#39;<\/span><span class=\"p\">].<\/span><span class=\"nx\">forEach<\/span><span class=\"p\">(<\/span><span class=\"nx\">type<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">Toast<\/span><span class=\"p\">[<\/span><span class=\"nx\">type<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(...<\/span><span class=\"nx\">configs<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">openToast<\/span><span class=\"p\">({<\/span> <span class=\"nx\">type<\/span><span class=\"p\">,<\/span> <span class=\"p\">...<\/span><span class=\"nx\">configs<\/span> <span class=\"p\">})<\/span>\n<span class=\"p\">})<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"\u914d\u7f6e\u5bf9\u8c61\u4f20\u53c2\">\u914d\u7f6e\u5bf9\u8c61\u4f20\u53c2<\/h3>\n<p>\u9664\u4e86\u4e0a\u9762\u7684\u7b80\u7565\u53c2\u6570\u5916\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528\u5bf9\u8c61\u7684\u5f62\u5f0f\u4f20\u9012\u53c2\u6570\uff0c\u7528\u6765\u5b9a\u5236\u66f4\u5177\u4f53\u7684 Toast\uff1a<\/p>\n<ul>\n<li><code>Toast.success(config)<\/code><\/li>\n<li><code>Toast.error(config)<\/code><\/li>\n<li><code>Toast.info(config)<\/code><\/li>\n<li><code>Toast.warning(config)<\/code><\/li>\n<li><code>Toast.loading(config)<\/code><\/li>\n<\/ul>\n<p><code>config<\/code> \u5bf9\u8c61\u5c5e\u6027\u5982\u4e0b\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">\u53c2\u6570<\/th>\n<th style=\"text-align:left\">\u8bf4\u660e<\/th>\n<th style=\"text-align:left\">\u7c7b\u578b<\/th>\n<th style=\"text-align:left\">\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">className<\/td>\n<td style=\"text-align:left\">\u81ea\u5b9a\u4e49 CSS class<\/td>\n<td style=\"text-align:left\">string<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">content<\/td>\n<td style=\"text-align:left\">\u63d0\u793a\u5185\u5bb9<\/td>\n<td style=\"text-align:left\">ReactNode<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">duration<\/td>\n<td style=\"text-align:left\">\u81ea\u52a8\u5173\u95ed\u7684\u5ef6\u65f6\uff0c\u5355\u4f4d\u79d2\u3002\u8bbe\u4e3a 0 \u65f6\u4e0d\u81ea\u52a8\u5173\u95ed\uff0c\u4f1a\u5c55\u793a\u5173\u95ed\u56fe\u6807\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 <code>Toast.destroy(key)<\/code> \u5173\u95ed<\/td>\n<td style=\"text-align:left\">number<\/td>\n<td style=\"text-align:left\">3<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">icon<\/td>\n<td style=\"text-align:left\">\u81ea\u5b9a\u4e49\u56fe\u6807<\/td>\n<td style=\"text-align:left\">ReactNode<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">key<\/td>\n<td style=\"text-align:left\">\u5f53\u524d\u63d0\u793a\u7684\u552f\u4e00\u6807\u5fd7<\/td>\n<td style=\"text-align:left\">string | number<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">style<\/td>\n<td style=\"text-align:left\">\u81ea\u5b9a\u4e49\u5185\u8054\u6837\u5f0f<\/td>\n<td style=\"text-align:left\">CSSProperties<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">onClose<\/td>\n<td style=\"text-align:left\">\u5173\u95ed\u65f6\u89e6\u53d1\u7684\u56de\u8c03\u51fd\u6570<\/td>\n<td style=\"text-align:left\">function<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"\u5168\u5c40\u914d\u7f6e\">\u5168\u5c40\u914d\u7f6e<\/h3>\n<p>\u63d0\u4f9b <code>Toast.config(options)<\/code> \u914d\u7f6e Toast \u7684\u9ed8\u8ba4\u6837\u5f0f\u548c\u884c\u4e3a\uff0c\u5728\u5f15\u5165 Toast \u7684\u5165\u53e3\u6587\u4ef6\u4e2d\u914d\u7f6e\u3002<code>options<\/code> \u5c5e\u6027\u5982\u4e0b\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align:left\">\u53c2\u6570<\/th>\n<th style=\"text-align:left\">\u8bf4\u660e<\/th>\n<th style=\"text-align:left\">\u7c7b\u578b<\/th>\n<th style=\"text-align:left\">\u9ed8\u8ba4\u503c<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align:left\">duration<\/td>\n<td style=\"text-align:left\">\u9ed8\u8ba4\u81ea\u52a8\u5173\u95ed\u5ef6\u65f6\uff0c\u5355\u4f4d\u79d2<\/td>\n<td style=\"text-align:left\">number<\/td>\n<td style=\"text-align:left\">3<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">getContainer<\/td>\n<td style=\"text-align:left\">\u914d\u7f6e\u6e32\u67d3\u8282\u70b9\u7684\u8f93\u51fa\u4f4d\u7f6e<\/td>\n<td style=\"text-align:left\">() =&gt; HTMLElement<\/td>\n<td style=\"text-align:left\">() =&gt; document.body<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">maxCount<\/td>\n<td style=\"text-align:left\">\u6700\u5927\u663e\u793a\u6570, \u8d85\u8fc7\u9650\u5236\u65f6\uff0c\u6700\u65e9\u7684\u6d88\u606f\u4f1a\u88ab\u81ea\u52a8\u5173\u95ed<\/td>\n<td style=\"text-align:left\">number<\/td>\n<td style=\"text-align:left\">-<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left\">top<\/td>\n<td style=\"text-align:left\">\u6d88\u606f\u8ddd\u79bb\u9876\u90e8\u7684\u4f4d\u7f6e<\/td>\n<td style=\"text-align:left\">number<\/td>\n<td style=\"text-align:left\">24<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"\u5173\u95ed\u63d0\u793a\">\u5173\u95ed\u63d0\u793a<\/h3>\n<ul>\n<li><code>Toast.destroy()<\/code> \u5173\u95ed\u5f53\u524d\u6240\u6709\u7684 Toast\uff1b<\/li>\n<li><code>Toast.destroy(key)<\/code> \u5982\u679c\u5728 <code>config<\/code> \u5bf9\u8c61\u4e2d\u914d\u7f6e\u4e86\u4e00\u4e2a Toast \u7684\u552f\u4e00 <code>key<\/code>\uff0c\u53ef\u4ee5\u4f20\u9012 <code>key<\/code> \u53c2\u6570\u5173\u95ed\u6307\u5b9a\u7684 Toast\u3002<\/li>\n<\/ul>\n<h3 id=\"\u901a\u8fc7-key-\u66f4\u65b0-toast\">\u901a\u8fc7 key \u66f4\u65b0 Toast<\/h3>\n<p>\u53ef\u4ee5\u901a\u8fc7\u552f\u4e00\u7684 <code>key<\/code> \u6765\u52a8\u6001\u66f4\u65b0 Toast \u5185\u5bb9<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><span class=\"lnt\">8\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">key<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">&#39;updatable&#39;<\/span>\n\n<span class=\"kr\">const<\/span> <span class=\"nx\">openMessage<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">Toast<\/span><span class=\"p\">.<\/span><span class=\"nx\">loading<\/span><span class=\"p\">({<\/span> <span class=\"nx\">content<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;Loading...&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span> <span class=\"p\">});<\/span>\n  <span class=\"nx\">setTimeout<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">message<\/span><span class=\"p\">.<\/span><span class=\"nx\">success<\/span><span class=\"p\">({<\/span> <span class=\"nx\">content<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;Loaded!&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">duration<\/span><span class=\"o\">:<\/span> <span class=\"mi\">2<\/span> <span class=\"p\">});<\/span>\n  <span class=\"p\">},<\/span> <span class=\"mi\">1000<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"\u901a\u8fc7-hooks-\u83b7\u53d6\u4e0a\u4e0b\u6587\">\u901a\u8fc7 Hooks \u83b7\u53d6\u4e0a\u4e0b\u6587<\/h3>\n<p>\u5f53\u9700\u8981 context \u4fe1\u606f\uff08\u4f8b\u5982\u7236\u7ea7\u7ec4\u4ef6\u5411\u4e0b\u4f20\u9012\u7684\u5171\u4eab\u72b6\u6001\uff09\u65f6\uff0c\u53ef\u4ee5\u901a\u8fc7 <code>Toast.useToast()<\/code> \u521b\u5efa\u652f\u6301\u8bfb\u53d6 context \u7684 <code>contextHolder<\/code>\uff0c\u65b9\u6cd5\u4f1a\u8fd4\u56de <code>api<\/code> \u5b9e\u4f53\u4ee5\u53ca <code>contextHolder<\/code> \u8282\u70b9\u3002\u5c06\u5176\u63d2\u5165\u5230\u9700\u8981\u83b7\u53d6 context \u7684\u4f4d\u7f6e\u5373\u53ef\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-jsx\" data-lang=\"jsx\"><span class=\"kr\">const<\/span> <span class=\"nx\">Context<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">createContext<\/span><span class=\"p\">();<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">Demo<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">toast<\/span><span class=\"p\">,<\/span> <span class=\"nx\">contextHolder<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">Toast<\/span><span class=\"p\">.<\/span><span class=\"nx\">useToast<\/span><span class=\"p\">();<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">info<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">toast<\/span><span class=\"p\">.<\/span><span class=\"nx\">info<\/span><span class=\"p\">({<\/span>\n      <span class=\"c1\">\/\/ Access the closest Provider for this context above in the tree\n<\/span><span class=\"c1\"><\/span>      <span class=\"nx\">content<\/span><span class=\"o\">:<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">Context.Consumer<\/span><span class=\"p\">&gt;{({<\/span> <span class=\"nx\">name<\/span> <span class=\"p\">})<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"sb\">`Hello, <\/span><span class=\"si\">${<\/span><span class=\"nx\">name<\/span><span class=\"si\">}<\/span><span class=\"sb\">!`<\/span><span class=\"p\">}&lt;\/<\/span><span class=\"nt\">Context.Consumer<\/span><span class=\"p\">&gt;,<\/span>\n      <span class=\"nx\">duration<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">});<\/span>\n  <span class=\"p\">};<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\n    <span class=\"p\">&lt;<\/span><span class=\"nt\">Context.Provider<\/span> <span class=\"na\">value<\/span><span class=\"o\">=<\/span><span class=\"p\">{{<\/span> <span class=\"nx\">name<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;Toast hook&#39;<\/span> <span class=\"p\">}}&gt;<\/span>\n      <span class=\"p\">{<\/span><span class=\"cm\">\/* Receive the upper context value *\/<\/span><span class=\"p\">}<\/span>\n      <span class=\"p\">{<\/span><span class=\"nx\">contextHolder<\/span><span class=\"p\">}<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">button<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">info<\/span><span class=\"p\">}&gt;<\/span>\n        <span class=\"nx\">Display<\/span> <span class=\"nx\">normal<\/span> <span class=\"nx\">message<\/span>\n      <span class=\"p\">&lt;\/<\/span><span class=\"nt\">button<\/span><span class=\"p\">&gt;<\/span>\n    <span class=\"p\">&lt;\/<\/span><span class=\"nt\">Context.Provider<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"\u5b9e\u73b0\u601d\u8def-1\">\u5b9e\u73b0\u601d\u8def<\/h4>\n<p>\u76f4\u63a5\u8c03\u7528 Toast \u65b9\u6cd5\uff0c\u4f1a\u52a8\u6001\u521b\u5efa\u65b0\u7684 Toast \u5b9e\u4f8b\uff0c\u9ed8\u8ba4\u6e32\u67d3\u5728 body \u5e95\u90e8\u7684\u5bb9\u5668\u4e2d\uff0c\u6b64\u65f6\u5728 Toast \u4e2d\u8bbf\u95ee\u7684\u662f\u5bb9\u5668\u7684 context\u3002<\/p>\n<p>\u8981\u5728 Toast content \u5185\u8bbf\u95ee\u7236\u7ea7\u7ec4\u4ef6\u7684 context\uff0c\u9700\u8981\u628a content \u6302\u8f7d\u5230 <code>&lt;Context.Provider&gt;<\/code> \u7684 React \u5b50\u6811\u4e2d\uff0c\u8fd9\u6837 content \u4e2d\u7684 <code>&lt;Context.Consumer&gt;<\/code> \u624d\u80fd\u63a5\u6536\u5230\u7ed1\u5b9a\u7684 <code>value<\/code>\u3002\u4f46\u662f\u5982\u679c\u76f4\u63a5\u628a Toast \u6e32\u67d3\u5230\u7236\u7ea7\u7ec4\u4ef6\u4e0b\uff0c\u5373\u4f7f\u662f <code>fixed<\/code> \u5b9a\u4f4d\uff0c\u591a\u5c11\u4e5f\u4f1a\u53d7\u5230\u7236\u7ec4\u4ef6\u7684\u5e72\u6270\uff08\u6837\u5f0f\u3001\u751f\u547d\u5468\u671f\u7b49\uff09\uff0c\u6240\u4ee5\u4e3a\u4e86\u907f\u514d\u7236\u7ec4\u4ef6\u7684\u5f71\u54cd\uff0c\u540c\u65f6\u81ea\u52a8\u5e94\u7528\u8fc7\u6e21\u52a8\u753b\uff0c\u9700\u8981\u5728\u4e00\u4e2a\u4e13\u7528\u7684 Toast \u5bb9\u5668\u73af\u5883\u4e2d\u8ba9 Toast \u548c\u666e\u901a\u8c03\u7528\u4e00\u6837\u6e32\u67d3\uff0c\u5373\u9ed8\u8ba4\u7684 body \u5e95\u90e8\u5bb9\u5668\u3002<\/p>\n<p>\u8de8\u7ec4\u4ef6\u6811\u5f02\u5730\u6e32\u67d3\u6b63\u662f <code>React.createPortal()<\/code> \u7684\u7528\u6b66\u4e4b\u5730\u3002<\/p>\n<p>\u901a\u8fc7 <code>Toast.useToast()<\/code> \u8fd4\u56de\u7684 <code>toast<\/code> api\uff0c\u5728\u4e8b\u4ef6\u4e2d\u89e6\u53d1\u63d0\u793a\u540e\uff0c\u4f1a\u52a8\u6001\u521b\u5efa Toast \u5b9e\u4f8b\uff08\u4f5c\u4e3a contextHolder \u63d2\u5165\u5230\u7236\u7ec4\u4ef6\u5b50\u6811\uff09\uff0cToast render \u4e2d\u5224\u65ad\u662f hook \u89e6\u53d1\u5219\u5229\u7528 <code>React.createPortal(&lt;ToastContent \/&gt;, bodyContainer)<\/code> \u628a <strong>ToastContent<\/strong> \u6e32\u67d3\u5230\u9ed8\u8ba4\u5bb9\u5668\u4e2d\uff0c\u8fd9\u6837 ToastContent \u5373\u6210\u4e3a\u4e86 <code>&lt;Context.Provider&gt;<\/code> \u5b50\u6811\u4e2d\u7684\u7ec4\u4ef6\uff0c\u5b9e\u73b0\u8bbf\u95ee\u7236\u7ea7 context\uff0c\u53c8\u80fd\u5728\u9ed8\u8ba4\u5bb9\u5668\u4e2d\u6b63\u5e38\u6e32\u67d3\u3002<\/p>\n<p>\u4f7f\u7528\u4ee3\u7801\u7b80\u7565\u8bf4\u660e\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kd\">function<\/span> <span class=\"nx\">useToast<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n\t<span class=\"kr\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">element<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setElement<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"kc\">null<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"kd\">function<\/span> <span class=\"nx\">toast<\/span><span class=\"p\">(<\/span><span class=\"nx\">props<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ Toast \u5bb9\u5668\u5df2\u7ecf\u6302\u8f7d\u5230 body \u5e95\u90e8\n<\/span><span class=\"c1\"><\/span>    <span class=\"kr\">const<\/span> <span class=\"nx\">containerCallback<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">container<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"c1\">\/\/ \u52a8\u6001\u521b\u5efa Toast \u5b9e\u4f8b\n<\/span><span class=\"c1\"><\/span>      <span class=\"kr\">const<\/span> <span class=\"nx\">toastElem<\/span> <span class=\"o\">=<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">Toast<\/span> <span class=\"nx\">container<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">container<\/span><span class=\"p\">}<\/span> <span class=\"o\">\/&gt;<\/span>\n      <span class=\"nx\">setElement<\/span><span class=\"p\">(<\/span><span class=\"nx\">toastElem<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"nx\">addToast<\/span><span class=\"p\">({<\/span> <span class=\"p\">...<\/span><span class=\"nx\">props<\/span><span class=\"p\">,<\/span> <span class=\"nx\">containerCallback<\/span> <span class=\"p\">})<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">[<\/span><span class=\"nx\">toast<\/span><span class=\"p\">,<\/span> <span class=\"nx\">element<\/span><span class=\"p\">]<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">addToast<\/span><span class=\"p\">({<\/span> <span class=\"nx\">containerCallback<\/span> <span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">containerCallback<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ hook \u8c03\u7528\uff0c\u5728 body \u5e95\u90e8\u52a8\u6001\u521b\u5efa Toast \u5bb9\u5668\uff0cmount \u540e\u4f20\u9012 DOM \u8282\u70b9\n<\/span><span class=\"c1\"><\/span>    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\n      <span class=\"o\">&lt;<\/span><span class=\"nx\">div<\/span> <span class=\"nx\">ref<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">div<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">div<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">containerCallback<\/span><span class=\"p\">(<\/span><span class=\"nx\">div<\/span><span class=\"p\">)}<\/span> <span class=\"o\">\/&gt;<\/span>\n    <span class=\"p\">)<\/span>\n  <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">Toast<\/span> <span class=\"o\">\/&gt;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">Toast<\/span><span class=\"p\">({<\/span> <span class=\"nx\">container<\/span> <span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">container<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ hook \u8c03\u7528\uff0c\u4e0d\u6e32\u67d3\u5230\u7236\u7ec4\u4ef6\u4e0b\n<\/span><span class=\"c1\"><\/span>    <span class=\"k\">return<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">createPortal<\/span><span class=\"p\">(<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">ToastContent<\/span> <span class=\"o\">\/&gt;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">container<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ \u666e\u901a\u8c03\u7528\uff0c\u6b63\u5e38\u6e32\u67d3\n<\/span><span class=\"c1\"><\/span>    <span class=\"k\">return<\/span> <span class=\"o\">&lt;<\/span><span class=\"nx\">ToastContent<\/span> <span class=\"o\">\/&gt;<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2>\n<p>\u901a\u8fc7\u8bbe\u8ba1 Alert \u548c Toast \u7684\u5c55\u793a\u4ea4\u4e92\u548c API\uff0c\u80fd\u591f\u4ece\u666e\u901a\u7528\u6237\u3001\u7ec4\u4ef6\u4f7f\u7528\u65b9\u3001\u7ec4\u4ef6\u63d0\u4f9b\u65b9\u7684\u89d2\u5ea6\u8003\u8651\u5982\u4f55\u505a\u597d\u4e00\u4e2a\u901a\u7528\u7ec4\u4ef6\uff1b\u4e0d\u540c\u7684\u7ec4\u4ef6\u5e93\u6709\u4e0d\u540c\u7684\u98ce\u683c\uff0c\u4f46\u6c89\u6dc0\u51fa\u6765\u7684\u4f18\u79c0\u5b9e\u8df5\u90fd\u5927\u540c\u5c0f\u5f02\u3002<\/p>\n<p>\u6709\u4e86\u8bbe\u8ba1\u65b9\u6848\u540e\u624d\u8003\u8651\u600e\u4e48\u4f18\u96c5\u5730\u5b9e\u73b0\u8fd9\u4e9b\u529f\u80fd\uff0c\u5173\u8054\u7ec4\u4ef6\u5e93\u3001\u89e3\u51b3\u517c\u5bb9\u95ee\u9898\u3001\u5904\u7406\u5404\u79cd\u7ec6\u8282\u7b49\uff0c\u9010\u6b65\u6253\u78e8\u6210\u719f\u3002<\/p>\n<h2 id=\"\u53c2\u8003\">\u53c2\u8003<\/h2>\n<p><a href=\"https:\/\/ant-design.gitee.io\/components\/message-cn\/\">Ant Design Message \u5168\u5c40\u63d0\u793a<\/a><\/p>\n<p><a href=\"https:\/\/ant-design.gitee.io\/components\/alert-cn\/\">Ant Design Alert \u8b66\u544a\u63d0\u793a<\/a><\/p>\n<p><a href=\"https:\/\/people-design.bytedance.net\/docs\/component\/coponent-feedback-global-prompt-cn\">People Design \u5168\u5c40\u63d0\u793a<\/a><\/p>\n<p><a href=\"https:\/\/people-design.bytedance.net\/docs\/component\/coponent-feedback-warning-cn\">People Design \u5e38\u9a7b\u63d0\u793a<\/a><\/p>\n<p><a href=\"https:\/\/material-ui.com\/components\/alert\/\">Material-UI Alert<\/a><\/p>\n<p><a href=\"https:\/\/material-ui.com\/components\/snackbars\/\">Material-UI Snackbar<\/a><\/p>"},{"title":"\u3010\u8bd1\u3011\u4ec0\u4e48\u65f6\u5019\u4f7f\u7528 useMemo \u548c useCallback","link":"https:\/\/jancat.github.io\/post\/2019\/translation-usememo-and-usecallback\/","pubDate":"Mon, 19 Aug 2019 21:18:32 +0800","guid":"https:\/\/jancat.github.io\/post\/2019\/translation-usememo-and-usecallback\/","description":"<blockquote>\n<p>\u539f\u6587\uff1a<a href=\"https:\/\/kentcdodds.com\/blog\/usememo-and-usecallback\">When to useMemo and useCallback<\/a><\/p>\n<\/blockquote>\n<p>\u6027\u80fd\u4f18\u5316\u603b\u662f\u4f1a\u6709\u6210\u672c\uff0c\u4f46\u5e76\u4e0d\u603b\u662f\u5e26\u6765\u597d\u5904\u3002\u6211\u4eec\u6765\u8c08\u8c08 <code>useMemo<\/code> \u548c <code>useCallback<\/code> \u7684\u6210\u672c\u548c\u6536\u76ca\u3002<\/p>\n<p>\u8fd9\u91cc\u662f\u4e00\u4e2a\u7cd6\u679c\u63d0\u552e\u8d27\u673a\uff1a<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190730212055.png\" alt=\"\"><\/p>\n<p>\uff08\u539f\u6587\u4e2d\u53ef\u70b9\u51fb\u4ea4\u4e92\uff0c\u70b9\u51fb &ldquo;grab&rdquo; \u6309\u94ae\u540e\u201c\u63d0\u53d6\u201d\u5bf9\u5e94\u7684\u7cd6\u679c\uff0c\u5bf9\u5e94\u9879\u4f1a\u4ece\u9875\u9762\u5220\u9664\uff1b\u5168\u90e8\u63d0\u53d6\u5b8c\u540e\u4f1a\u51fa\u73b0 &ldquo;refill&rdquo; \u6309\u94ae\uff0c\u70b9\u51fb\u91cd\u7f6e\u6240\u6709\u7cd6\u679c\uff09<\/p>\n<p>\u4ee5\u4e0b\u662f\u5b83\u7684\u5b9e\u73b0\u65b9\u5f0f\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kd\">function<\/span> <span class=\"nx\">CandyDispenser<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">initialCandies<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"s1\">&#39;snickers&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;skittles&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;twix&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;milky way&#39;<\/span><span class=\"p\">]<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">candies<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setCandies<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"nx\">initialCandies<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">dispense<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">candy<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">setCandies<\/span><span class=\"p\">(<\/span><span class=\"nx\">allCandies<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">allCandies<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">!==<\/span> <span class=\"nx\">candy<\/span><span class=\"p\">))<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\n    <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">h1<\/span><span class=\"p\">&gt;<\/span><span class=\"nx\">Candy<\/span> <span class=\"nx\">Dispenser<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">h1<\/span><span class=\"p\">&gt;<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n        <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span><span class=\"nx\">Available<\/span> <span class=\"nx\">Candy<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n        <span class=\"p\">{<\/span><span class=\"nx\">candies<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span> <span class=\"o\">===<\/span> <span class=\"mi\">0<\/span> <span class=\"o\">?<\/span> <span class=\"p\">(<\/span>\n          <span class=\"p\">&lt;<\/span><span class=\"nt\">button<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">setCandies<\/span><span class=\"p\">(<\/span><span class=\"nx\">initialCandies<\/span><span class=\"p\">)}&gt;<\/span><span class=\"nx\">refill<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">button<\/span><span class=\"p\">&gt;<\/span>\n        <span class=\"p\">)<\/span> <span class=\"o\">:<\/span> <span class=\"p\">(<\/span>\n          <span class=\"p\">&lt;<\/span><span class=\"nt\">ul<\/span><span class=\"p\">&gt;<\/span>\n            <span class=\"p\">{<\/span><span class=\"nx\">candies<\/span><span class=\"p\">.<\/span><span class=\"nx\">map<\/span><span class=\"p\">(<\/span><span class=\"nx\">candy<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">(<\/span>\n              <span class=\"p\">&lt;<\/span><span class=\"nt\">li<\/span> <span class=\"na\">key<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">candy<\/span><span class=\"p\">}&gt;<\/span>\n                <span class=\"p\">&lt;<\/span><span class=\"nt\">button<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">dispense<\/span><span class=\"p\">(<\/span><span class=\"nx\">candy<\/span><span class=\"p\">)}&gt;<\/span><span class=\"nx\">grab<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">button<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span><span class=\"nx\">candy<\/span><span class=\"p\">}<\/span>\n              <span class=\"p\">&lt;\/<\/span><span class=\"nt\">li<\/span><span class=\"p\">&gt;<\/span>\n            <span class=\"p\">))}<\/span>\n          <span class=\"p\">&lt;\/<\/span><span class=\"nt\">ul<\/span><span class=\"p\">&gt;<\/span>\n        <span class=\"p\">)}<\/span>\n      <span class=\"p\">&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n    <span class=\"p\">&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n  <span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u73b0\u5728\u6211\u60f3\u95ee\u4f60\u4e00\u4e2a\u95ee\u9898\uff0c\u6211\u5e0c\u671b\u4f60\u5728\u7ee7\u7eed\u4e4b\u524d\u597d\u597d\u60f3\u60f3\u3002\u6211\u8981\u505a\u4e00\u4e2a\u6539\u53d8\uff0c\u6211\u60f3\u8ba9\u4f60\u544a\u8bc9\u6211\u54ea\u4e00\u4e2a\u4f1a\u6709\u66f4\u597d\u7684\u6027\u80fd\u7279\u5f81\u3002<\/p>\n<p>\u6211\u552f\u4e00\u8981\u6539\u53d8\u7684\u662f\u5728 <code>React.useCallback<\/code> \u91cc\u5305\u88f9 <code>dispense<\/code> \u51fd\u6570\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kr\">const<\/span> <span class=\"nx\">dispense<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useCallback<\/span><span class=\"p\">(<\/span><span class=\"nx\">candy<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">setCandies<\/span><span class=\"p\">(<\/span><span class=\"nx\">allCandies<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">allCandies<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">!==<\/span> <span class=\"nx\">candy<\/span><span class=\"p\">))<\/span>\n<span class=\"p\">},<\/span> <span class=\"p\">[])<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8fd9\u662f<strong>\u539f\u6765<\/strong>\u7684\u4ee3\u7801\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kr\">const<\/span> <span class=\"nx\">dispense<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">candy<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">setCandies<\/span><span class=\"p\">(<\/span><span class=\"nx\">allCandies<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">allCandies<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">!==<\/span> <span class=\"nx\">candy<\/span><span class=\"p\">))<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6240\u4ee5\u6211\u7684\u95ee\u9898\u662f\uff0c\u5728\u8fd9\u4e2a\u7279\u5b9a\u7684\u4f8b\u5b50\u4e2d\uff0c\u54ea\u4e00\u4e2a\u5bf9\u6027\u80fd\u66f4\u597d\uff1f\u539f\u6765\u7684\u8fd8\u662f <code>useCallback<\/code>\uff1f<\/p>\n<p>\u5982\u679c\u4f60\u9009\u62e9\u7684\u662f <code>useCallback<\/code>\uff0c\u518d\u597d\u597d\u601d\u8003\u4e0b\u3002<\/p>\n<p>\u6b63\u786e\u7b54\u6848\u662f\uff1a\u4f7f\u7528\u539f\u6765\u7684\u4ee3\u7801\u6027\u80fd\u4f1a\u66f4\u597d\ud83d\ude09<\/p>\n<h2 id=\"\u4e3a\u4ec0\u4e48-usecallback-\u66f4\u7cdf\u7cd5\">\u4e3a\u4ec0\u4e48 useCallback \u66f4\u7cdf\u7cd5\uff1f\uff01<\/h2>\n<p>\u6211\u4eec\u542c\u5230\u5f88\u591a\u4f60\u5e94\u8be5\u4f7f\u7528 <code>React.useCallback<\/code> \u6765\u63d0\u9ad8\u6027\u80fd\uff0c\u5e76\u4e14\u201c\u5185\u8054\u51fd\u6570\u53ef\u80fd\u4f1a\u5bf9\u6027\u80fd\u9020\u6210\u95ee\u9898\u201d\uff0c\u90a3\u4e48\u4e0d\u4f7f\u7528<code>callCallback<\/code> \u662f\u5982\u4f55\u53d8\u5f97\u66f4\u597d\u7684\uff1f<\/p>\n<p>\u4ece\u6211\u4eec\u7684\u5177\u4f53\u4f8b\u5b50\u4e2d\u9000\u540e\u4e00\u6b65\uff0c\u751a\u81f3\u4eceReact\u90a3\u91cc\u8003\u8651\u4e00\u4e0b\uff1a<strong>\u6267\u884c\u7684\u6bcf\u884c\u4ee3\u7801\u90fd\u6709\u6210\u672c<\/strong>\u3002\u8ba9\u6211\u7a0d\u5fae\u91cd\u6784\u4e00\u4e0b <code>useCallback<\/code> \u7684\u4f8b\u5b50\u6765\u66f4\u6e05\u695a\u5730\u8bf4\u660e\u4e8b\u60c5\uff08\u6ca1\u6709\u5b9e\u9645\u7684\u6539\u53d8\uff0c\u53ea\u662f\u79fb\u52a8\u4e0b\u4ee3\u7801\uff09\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kr\">const<\/span> <span class=\"nx\">dispense<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">candy<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">setCandies<\/span><span class=\"p\">(<\/span><span class=\"nx\">allCandies<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">allCandies<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">!==<\/span> <span class=\"nx\">candy<\/span><span class=\"p\">))<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">dispenseCallback<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useCallback<\/span><span class=\"p\">(<\/span><span class=\"nx\">dispense<\/span><span class=\"p\">,<\/span> <span class=\"p\">[])<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8fd9\u662f\u539f\u6765\u7684\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kr\">const<\/span> <span class=\"nx\">dispense<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">candy<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">setCandies<\/span><span class=\"p\">(<\/span><span class=\"nx\">allCandies<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">allCandies<\/span><span class=\"p\">.<\/span><span class=\"nx\">filter<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">!==<\/span> <span class=\"nx\">candy<\/span><span class=\"p\">))<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6ce8\u610f\u5230\u4e86\u5417\uff1f\u8ba9\u6211\u4eec\u770b\u4e00\u4e0b diff\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-diff\" data-lang=\"diff\">const dispense = candy =&gt; {\n    setCandies(allCandies =&gt; allCandies.filter(c =&gt; c !== candy))\n  }\n<span class=\"gi\">+ const dispenseCallback = React.useCallback(dispense, [])\n<\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u662f\u7684\uff0c\u9664\u4e86<code>useCallback<\/code>\u7248\u672c\u505a\u4e86\u66f4\u591a\u7684\u5de5\u4f5c\u4e4b\u5916\uff0c\u5b83\u4eec\u5b8c\u5168\u76f8\u540c\u3002 \u6211\u4eec\u4e0d\u4ec5\u9700\u8981\u5b9a\u4e49\u51fd\u6570\uff0c\u8fd8\u8981\u5b9a\u4e49\u4e00\u4e2a\u6570\u7ec4\uff08<code>[]<\/code>\uff09\u5e76\u8c03\u7528 <code>React.useCallback<\/code>\uff0c\u5b83\u672c\u8eab\u4f1a\u8bbe\u7f6e\u5c5e\u6027\u548c\u8fd0\u884c\u903b\u8f91\u8868\u8fbe\u5f0f\u7b49\u3002<\/p>\n<p>\u56e0\u6b64\uff0c\u5728\u8fd9\u4e24\u79cd\u60c5\u51b5\u4e0b\uff0cJavaScript \u5fc5\u987b\u5728\u6bcf\u6b21\u6e32\u67d3\u4e2d\u4e3a\u51fd\u6570\u5b9a\u4e49\u5206\u914d\u5185\u5b58\uff0c\u5e76\u4e14\u6839\u636e <code>useCallback<\/code> \u7684\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4f60\u53ef\u80fd\u4f1a\u83b7\u5f97\u66f4\u591a\u7684\u51fd\u6570\u5b9a\u4e49\u5185\u5b58\u5206\u914d\uff08\u5b9e\u9645\u60c5\u51b5\u5e76\u975e\u5982\u6b64\uff0c\u4f46\u91cd\u70b9\u8fd8\u5728\u8fd9\u91cc\uff09\u3002\u8fd9\u5c31\u662f\u6211\u8bd5\u56fe\u901a\u8fc7\u6211\u7684 Twitter \u6c11\u610f\u8c03\u67e5\u5f97\u5230\u7684\uff1a<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190730215347.png\" alt=\"\"><\/p>\n<p>\u6211\u8fd8\u60f3\u63d0\u4e00\u4e0b\uff0c\u5728\u7ec4\u4ef6\u7684\u7b2c\u4e8c\u6b21\u6e32\u67d3\u4e2d\uff0c\u539f\u6765\u7684 <code>dispense<\/code> \u51fd\u6570\u88ab\u5783\u573e\u6536\u96c6\uff08\u91ca\u653e\u5185\u5b58\u7a7a\u95f4\uff09\uff0c\u7136\u540e\u521b\u5efa\u4e00\u4e2a\u65b0\u7684 <code>dispense<\/code> \u51fd\u6570\u3002 \u4f46\u662f\u4f7f\u7528 <code>useCallback<\/code> \u65f6\uff0c\u539f\u6765\u7684 <code>dispense<\/code> \u51fd\u6570\u4e0d\u4f1a\u88ab\u5783\u573e\u6536\u96c6\uff0c\u5e76\u4e14\u4f1a\u521b\u5efa\u4e00\u4e2a\u65b0\u7684 <code>dispense<\/code> \u51fd\u6570\uff0c\u6240\u4ee5\u4ece\u5185\u5b58\u7684\u89d2\u5ea6\u6765\u770b\uff0c\u8fd9\u4f1a\u53d8\u5f97\u66f4\u7cdf\u3002<\/p>\n<p>\u4f5c\u4e3a\u4e00\u4e2a\u76f8\u5173\u7684\u8bf4\u660e\uff0c\u5982\u679c\u4f60\u6709\u5176\u5b83\u4f9d\u8d56\uff0c\u90a3\u4e48React\u5f88\u53ef\u80fd\u4f1a\u6302\u8d77\u5bf9\u524d\u9762\u51fd\u6570\u7684\u5f15\u7528\uff0c\u56e0\u4e3a <strong>memoization<\/strong> \u901a\u5e38\u610f\u5473\u7740\u6211\u4eec\u4fdd\u7559\u65e7\u503c\u7684\u526f\u672c\uff0c\u4ee5\u4fbf\u5728\u6211\u4eec\u83b7\u5f97\u4e0e\u5148\u524d\u7ed9\u51fa\u7684\u76f8\u540c\u4f9d\u8d56\u7684\u60c5\u51b5\u4e0b\u8fd4\u56de\u3002 \u7279\u522b\u806a\u660e\u7684\u4f60\u4f1a\u6ce8\u610f\u5230\uff0c\u8fd9\u610f\u5473\u7740React\u8fd8\u5fc5\u987b\u6302\u5728\u5bf9\u8fd9\u4e2a\u7b49\u5f0f\u68c0\u67e5\u4f9d\u8d56\u9879\u7684\u5f15\u7528\u4e0a\uff08\u7531\u4e8e\u95ed\u5305\uff0c\u8fd9\u79cd\u60c5\u51b5\u53ef\u80fd\u4f1a\u5076\u7136\u53d1\u751f\uff0c\u4f46\u65e0\u8bba\u5982\u4f55\u5b83\u90fd\u503c\u5f97\u4e00\u63d0\uff09\u3002<\/p>\n<h2 id=\"usememo-\u867d\u7136\u4e0d\u540c\u4f46\u5374\u662f\u76f8\u4f3c\u7684\">useMemo \u867d\u7136\u4e0d\u540c\uff0c\u4f46\u5374\u662f\u76f8\u4f3c\u7684\uff1f<\/h2>\n<p><code>useMemo<\/code> \u7c7b\u4f3c\u4e8e <code>useCallback<\/code>\uff0c\u9664\u4e86\u5b83\u5141\u8bb8\u4f60\u5c06 <strong>memoization<\/strong> \u5e94\u7528\u4e8e\u4efb\u4f55\u503c\u7c7b\u578b\uff08\u4e0d\u4ec5\u4ec5\u662f\u51fd\u6570\uff09\u3002 \u5b83\u901a\u8fc7\u63a5\u53d7\u4e00\u4e2a\u8fd4\u56de\u503c\u7684\u51fd\u6570\u6765\u5b9e\u73b0\u8fd9\u4e00\u70b9\uff0c\u7136\u540e<strong>\u53ea\u5728<\/strong>\u9700\u8981\u68c0\u7d22\u503c\u65f6\u8c03\u7528\u8be5\u51fd\u6570\uff08\u901a\u5e38\u8fd9\u53ea\u6709\u5728\u6bcf\u6b21\u6e32\u67d3\u4e2d\u4f9d\u8d56\u9879\u6570\u7ec4\u4e2d\u7684\u5143\u7d20\u53d1\u751f\u53d8\u5316\u65f6\u624d\u4f1a\u53d1\u751f\u4e00\u6b21\uff09\u3002<\/p>\n<p>\u6240\u4ee5\uff0c\u5982\u679c\u6211\u4e0d\u60f3\u5728\u6bcf\u6b21\u6e32\u67d3\u65f6\u521d\u59cb\u5316\u90a3\u4e2a <code>initialCandies<\/code> \u6570\u7ec4\uff0c\u6211\u53ef\u4ee5\u505a\u8fd9\u4e2a\u6539\u53d8\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-diff\" data-lang=\"diff\"><span class=\"gd\">- const initialCandies = [&#39;snickers&#39;, &#39;skittles&#39;, &#39;twix&#39;, &#39;milky way&#39;]\n<\/span><span class=\"gd\"><\/span><span class=\"gi\">+ const initialCandies = React.useMemo(\n<\/span><span class=\"gi\">+  () =&gt; [&#39;snickers&#39;, &#39;skittles&#39;, &#39;twix&#39;, &#39;milky way&#39;],\n<\/span><span class=\"gi\">+  [],\n<\/span><span class=\"gi\">+ )\n<\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6211\u53ef\u4ee5\u907f\u514d\u90a3\u4e2a\u95ee\u9898\uff0c\u4f46\u662f\u8282\u7701\u7684\u6210\u672c\u662f\u5982\u6b64\u4e4b\u5c0f\uff0c\u4ee5\u81f3\u4e8e\u6362\u6765\u4f7f\u4ee3\u7801\u66f4\u52a0\u590d\u6742\u7684\u6210\u672c\u662f\u4e0d\u503c\u5f97\u7684\u3002\u5b9e\u9645\u4e0a\uff0c\u8fd9\u91cc\u4f7f\u7528<code>useMemo<\/code> \u4e5f\u53ef\u80fd\u4f1a\u66f4\u7cdf\uff0c\u56e0\u4e3a\u6211\u4eec\u518d\u6b21\u8fdb\u884c\u4e86\u51fd\u6570\u8c03\u7528\uff0c\u5e76\u4e14\u4ee3\u7801\u4f1a\u6267\u884c\u5c5e\u6027\u8d4b\u503c\u7b49\u3002<\/p>\n<p>\u5728\u8fd9\u4e2a\u7279\u5b9a\u7684\u573a\u666f\u4e2d\uff0c\u66f4\u597d\u7684\u65b9\u6cd5\u662f\u8fdb\u884c\u8fd9\u4e2a\u66f4\u6539\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-diff\" data-lang=\"diff\"><span class=\"gi\">+ const initialCandies = [&#39;snickers&#39;, &#39;skittles&#39;, &#39;twix&#39;, &#39;milky way&#39;]\n<\/span><span class=\"gi\"><\/span>  function CandyDispenser() {\n<span class=\"gd\">-   const initialCandies = [&#39;snickers&#39;, &#39;skittles&#39;, &#39;twix&#39;, &#39;milky way&#39;]\n<\/span><span class=\"gd\"><\/span>    const [candies, setCandies] = React.useState(initialCandies)\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u4f46\u6709\u65f6\u4f60\u6ca1\u6709\u90a3\u4e48\u5962\u4f88\uff0c\u56e0\u4e3a\u8fd9\u4e2a\u503c\u8981\u4e48\u6765\u6e90\u4e8e <code>props<\/code> \u6216\u8005\u51fd\u6570\u4f53\u5185\u521d\u59cb\u5316\u7684\u5176\u5b83\u53d8\u91cf\u3002<\/p>\n<p>\u5173\u952e\u662f\u8fd9\u4e24\u79cd\u65b9\u5f0f\u65e0\u5173\u7d27\u8981\uff0c\u4f18\u5316\u8fd9\u4e9b\u4ee3\u7801\u7684\u597d\u5904\u662f\u5982\u6b64\u5fae\u4e0d\u8db3\u9053\uff0c\u4ee5\u81f3\u4e8e\u4f60\u53ef\u4ee5\u66f4\u597d\u5730\u82b1\u65f6\u95f4\u6765\u6539\u5584\u4ea7\u54c1\u8d28\u91cf\u3002<\/p>\n<h2 id=\"\u91cd\u70b9\u662f\u4ec0\u4e48\">\u91cd\u70b9\u662f\u4ec0\u4e48\uff1f<\/h2>\n<p>\u91cd\u70b9\u662f\uff1a<\/p>\n<p><strong>\u6027\u80fd\u4f18\u5316\u4e0d\u662f\u514d\u8d39\u7684\u3002 \u5b83\u4eec\u603b\u662f\u5e26\u6765\u6210\u672c\uff0c\u4f46\u8fd9\u5e76\u4e0d\u603b\u662f\u5e26\u6765\u597d\u5904\u6765\u62b5\u6d88\u6210\u672c\u3002<\/strong><\/p>\n<p>\u56e0\u6b64\uff0c\u8d1f\u8d23\u4efb\u5730\u8fdb\u884c\u4f18\u5316\u3002<\/p>\n<h2 id=\"\u6240\u4ee5\u6211\u5e94\u8be5\u4ec0\u4e48\u65f6\u5019\u4f7f\u7528-usememo-\u548c-usecallback\">\u6240\u4ee5\u6211\u5e94\u8be5\u4ec0\u4e48\u65f6\u5019\u4f7f\u7528 useMemo \u548c useCallback\uff1f<\/h2>\n<p>\u8fd9\u4e24\u4e2a hooks \u5185\u7f6e\u4e8e React \u90fd\u6709\u7279\u522b\u7684\u539f\u56e0\uff1a<\/p>\n<ol>\n<li>\u5f15\u7528\u76f8\u7b49<\/li>\n<li>\u6602\u8d35\u7684\u8ba1\u7b97<\/li>\n<\/ol>\n<h2 id=\"\u5f15\u7528\u76f8\u7b49\">\u5f15\u7528\u76f8\u7b49<\/h2>\n<p>\u5982\u679c\u4f60\u662f JavaScript \u6216\u8005\u7f16\u7a0b\u65b0\u624b\uff0c\u4f60\u5f88\u5feb\u5c31\u4f1a\u660e\u767d\u4e3a\u4ec0\u4e48\u4f1a\u8fd9\u6837\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kc\">true<\/span> <span class=\"o\">===<\/span> <span class=\"kc\">true<\/span> <span class=\"c1\">\/\/ true\n<\/span><span class=\"c1\"><\/span><span class=\"kc\">false<\/span> <span class=\"o\">===<\/span> <span class=\"kc\">false<\/span> <span class=\"c1\">\/\/ true\n<\/span><span class=\"c1\"><\/span><span class=\"mi\">1<\/span> <span class=\"o\">===<\/span> <span class=\"mi\">1<\/span> <span class=\"c1\">\/\/ true\n<\/span><span class=\"c1\"><\/span><span class=\"s1\">&#39;a&#39;<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;a&#39;<\/span> <span class=\"c1\">\/\/ true\n<\/span><span class=\"c1\"><\/span>\n<span class=\"p\">{}<\/span> <span class=\"o\">===<\/span> <span class=\"p\">{}<\/span> <span class=\"c1\">\/\/ false\n<\/span><span class=\"c1\"><\/span><span class=\"p\">[]<\/span> <span class=\"o\">===<\/span> <span class=\"p\">[]<\/span> <span class=\"c1\">\/\/ false\n<\/span><span class=\"c1\"><\/span><span class=\"p\">()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{}<\/span> <span class=\"o\">===<\/span> <span class=\"p\">()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{}<\/span> <span class=\"c1\">\/\/ false\n<\/span><span class=\"c1\"><\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">z<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n<span class=\"nx\">z<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">z<\/span> <span class=\"c1\">\/\/ true\n<\/span><span class=\"c1\"><\/span>\n<span class=\"c1\">\/\/ NOTE: React actually uses Object.is, but it&#39;s very similar to ===\n<\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6211\u4e0d\u6253\u7b97\u6df1\u5165\u7814\u7a76\u8fd9\u4e2a\u95ee\u9898\uff0c\u4f46\u662f\u5f53\u4f60\u5728React\u51fd\u6570\u7ec4\u4ef6\u4e2d\u5b9a\u4e49\u4e00\u4e2a\u5bf9\u8c61\u65f6\uff0c\u5b83\u8ddf\u4e0a\u6b21\u5b9a\u4e49\u7684\u76f8\u540c\u5bf9\u8c61\uff0c\u5f15\u7528\u662f\u4e0d\u4e00\u6837\u7684\uff08\u5373\u4f7f\u5b83\u5177\u6709\u6240\u6709\u76f8\u540c\u503c\u548c\u76f8\u540c\u5c5e\u6027\uff09\uff0c\u8fd9\u8db3\u4ee5\u8bf4\u660e\u8fd9\u4e2a\u95ee\u9898\u3002<\/p>\n<p>\u5728React\u4e2d\uff0c\u6709\u4e24\u79cd\u60c5\u51b5\u4e0b\u5f15\u7528\u76f8\u7b49\u5f88\u91cd\u8981\uff0c\u8ba9\u6211\u4eec\u4e00\u4e2a\u4e2a\u5730\u6765\u770b\u3002<\/p>\n<h3 id=\"\u4f9d\u8d56\u5217\u8868\">\u4f9d\u8d56\u5217\u8868<\/h3>\n<p>\u8ba9\u6211\u4eec\u6765\u56de\u987e\u4e00\u4e2a\u4f8b\u5b50\u3002<\/p>\n<blockquote>\n<p>\u8b66\u544a\uff0c\u4f60\u5c06\u770b\u5230\u4e00\u4e9b\u4eba\u4e3a\u6545\u610f\u8bbe\u8ba1\u7684\u4ee3\u7801\u3002\u8bf7\u4e0d\u8981\u5439\u6bdb\u6c42\u75b5\uff0c\u53ea\u5173\u6ce8\u6982\u5ff5\uff0c\u8c22\u8c22\u3002<\/p>\n<\/blockquote>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kd\">function<\/span> <span class=\"nx\">Foo<\/span><span class=\"p\">({<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">}<\/span>\n  <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">buzz<\/span><span class=\"p\">(<\/span><span class=\"nx\">options<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">},<\/span> <span class=\"p\">[<\/span><span class=\"nx\">options<\/span><span class=\"p\">])<\/span> <span class=\"c1\">\/\/ we want this to re-run if bar or baz change\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span><span class=\"nx\">foobar<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">Blub<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">Foo<\/span> <span class=\"na\">bar<\/span><span class=\"o\">=<\/span><span class=\"s\">&#34;bar value&#34;<\/span> <span class=\"na\">baz<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"mi\">3<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8fd9\u91cc\u6709\u95ee\u9898\u7684\u539f\u56e0\u662f\u56e0\u4e3a <code>useEffect<\/code> \u5c06\u5bf9\u6bcf\u6b21\u6e32\u67d3\u4e2d\u5bf9 <code>options<\/code> \u8fdb\u884c\u5f15\u7528\u76f8\u7b49\u6027\u68c0\u67e5\uff0c\u5e76\u4e14\u7531\u4e8eJavaScript\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u6bcf\u6b21\u6e32\u67d3 <code>options<\/code> \u90fd\u662f\u65b0\u7684\uff0c\u6240\u4ee5\u5f53React\u6d4b\u8bd5 <code>options<\/code> \u662f\u5426\u5728\u6e32\u67d3\u4e4b\u95f4\u53d1\u751f\u53d8\u5316\u65f6\uff0c\u5b83\u5c06\u59cb\u7ec8\u8ba1\u7b97\u4e3a <code>true<\/code>\uff0c\u610f\u5473\u7740\u6bcf\u6b21\u6e32\u67d3\u540e\u90fd\u4f1a\u8c03\u7528 <code>useEffect<\/code> \u56de\u8c03\uff0c\u800c\u4e0d\u662f\u4ec5\u5728 <code>bar<\/code> \u548c <code>baz<\/code> \u66f4\u6539\u65f6\u8c03\u7528\u3002<\/p>\n<p>\u6211\u4eec\u53ef\u4ee5\u505a\u4e24\u4ef6\u4e8b\u6765\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><span class=\"lnt\">8\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"c1\">\/\/ option 1\n<\/span><span class=\"c1\"><\/span><span class=\"kd\">function<\/span> <span class=\"nx\">Foo<\/span><span class=\"p\">({<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">}<\/span>\n    <span class=\"nx\">buzz<\/span><span class=\"p\">(<\/span><span class=\"nx\">options<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">},<\/span> <span class=\"p\">[<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">])<\/span> <span class=\"c1\">\/\/ we want this to re-run if bar or baz change\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span><span class=\"nx\">foobar<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8fd9\u662f\u4e2a\u4e0d\u9519\u7684\u9009\u62e9\uff0c\u5982\u679c\u8fd9\u662f\u771f\u7684\uff0c\u6211\u5c31\u4f1a\u8fd9\u4e48\u505a\u3002<\/p>\n<p>\u4f46\u662f\u6709\u4e00\u79cd\u60c5\u51b5\u4e0b\uff1a\u5982\u679c <code>bar<\/code> \u6216\u8005 <code>baz<\/code> \u662f\uff08\u975e\u539f\u59cb\u503c\uff09\u5bf9\u8c61\u3001\u6570\u7ec4\u3001\u51fd\u6570\u7b49\uff0c\u8fd9\u4e0d\u662f\u4e00\u4e2a\u5b9e\u9645\u7684\u89e3\u51b3\u65b9\u6848\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kd\">function<\/span> <span class=\"nx\">Blub<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">bar<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{}<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">baz<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">]<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">Foo<\/span> <span class=\"na\">bar<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">bar<\/span><span class=\"p\">}<\/span> <span class=\"na\">baz<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">baz<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8fd9\u6b63\u662f <code>useCallback<\/code> \u548c <code>useMemo<\/code> \u5b58\u5728\u7684\u539f\u56e0\u3002\u4f60\u53ef\u4ee5\u8fd9\u6837\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff08\u73b0\u5728\u90fd\u653e\u4e00\u8d77\u4e86\uff09\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kd\">function<\/span> <span class=\"nx\">Foo<\/span><span class=\"p\">({<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useEffect<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">}<\/span>\n    <span class=\"nx\">buzz<\/span><span class=\"p\">(<\/span><span class=\"nx\">options<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">},<\/span> <span class=\"p\">[<\/span><span class=\"nx\">bar<\/span><span class=\"p\">,<\/span> <span class=\"nx\">baz<\/span><span class=\"p\">])<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span><span class=\"nx\">foobar<\/span><span class=\"p\">&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">Blub<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">bar<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useCallback<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{},<\/span> <span class=\"p\">[])<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">baz<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useMemo<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"mi\">2<\/span><span class=\"p\">,<\/span> <span class=\"mi\">3<\/span><span class=\"p\">],<\/span> <span class=\"p\">[])<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">Foo<\/span> <span class=\"na\">bar<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">bar<\/span><span class=\"p\">}<\/span> <span class=\"na\">baz<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">baz<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><blockquote>\n<p>\u8bf7\u6ce8\u610f\uff0c\u540c\u6837\u7684\u4e8b\u60c5\u4e5f\u9002\u7528\u4e8e\u4f20\u9012\u7ed9 <code>useEffect<\/code>, <code>useLayoutEffect<\/code><em>,<\/em> <code>useCallback<\/code>, \u548c  <code>useMemo<\/code> \u7684\u4f9d\u8d56\u9879\u6570\u7ec4\u3002<\/p>\n<\/blockquote>\n<h3 id=\"reactmemo\">React.memo<\/h3>\n<blockquote>\n<p>\u8b66\u544a\uff0c\u4f60\u5c06\u770b\u5230\u4e00\u4e9b\u4eba\u4e3a\u6545\u610f\u8bbe\u8ba1\u7684\u4ee3\u7801\u3002\u8bf7\u4e0d\u8981\u5439\u6bdb\u6c42\u75b5\uff0c\u53ea\u5173\u6ce8\u6982\u5ff5\uff0c\u8c22\u8c22\u3002<\/p>\n<\/blockquote>\n<p>\u770b\u770b\u8fd9\u4e2a\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kd\">function<\/span> <span class=\"nx\">CountButton<\/span><span class=\"p\">({<\/span><span class=\"nx\">onClick<\/span><span class=\"p\">,<\/span> <span class=\"nx\">count<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">button<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">onClick<\/span><span class=\"p\">}&gt;{<\/span><span class=\"nx\">count<\/span><span class=\"p\">}&lt;\/<\/span><span class=\"nt\">button<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">DualCounter<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">count1<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setCount1<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">increment1<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">setCount1<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"kr\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">count2<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setCount2<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">increment2<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">setCount2<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\n    <span class=\"p\">&lt;&gt;<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">CountButton<\/span> <span class=\"na\">count<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">count1<\/span><span class=\"p\">}<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">increment1<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">CountButton<\/span> <span class=\"na\">count<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">count2<\/span><span class=\"p\">}<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">increment2<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n    <span class=\"p\">&lt;\/&gt;<\/span>\n  <span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6bcf\u6b21\u5355\u51fb\u5176\u4e2d\u4efb\u4f55\u4e00\u4e2a\u6309\u94ae\u65f6\uff0c<code>DualCounter<\/code> \u7684\u72b6\u6001\u90fd\u4f1a\u53d1\u751f\u53d8\u5316\uff0c\u56e0\u6b64\u4f1a\u91cd\u65b0\u6e32\u67d3\uff0c\u7136\u540e\u91cd\u65b0\u6e32\u67d3\u4e24\u4e2a<code>CountButton<\/code>\u3002 \u4f46\u662f\uff0c\u5b9e\u9645\u4e0a\u53ea\u9700\u8981\u91cd\u65b0\u6e32\u67d3\u88ab\u70b9\u51fb\u7684\u90a3\u4e2a\u6309\u94ae\u5427\uff1f\u56e0\u6b64\uff0c\u5982\u679c\u4f60\u70b9\u51fb\u7b2c\u4e00\u4e2a\u6309\u94ae\uff0c\u5219\u7b2c\u4e8c\u4e2a\u4e5f\u4f1a\u91cd\u65b0\u6e32\u67d3\uff0c\u4f46\u6ca1\u6709\u4efb\u4f55\u53d8\u5316\uff0c\u6211\u4eec\u79f0\u4e4b\u4e3a\u201c\u4e0d\u5fc5\u8981\u7684\u91cd\u65b0\u6e32\u67d3\u201d\u3002<\/p>\n<p><strong>\u5927\u591a\u6570\u65f6\u5019\uff0c\u4f60\u4e0d\u9700\u8981\u8003\u8651\u53bb\u4f18\u5316\u4e0d\u5fc5\u8981\u7684\u91cd\u65b0\u6e32\u67d3<\/strong>\u3002React\u662f\u975e\u5e38\u5feb\u7684\uff0c\u6211\u80fd\u60f3\u5230\u4f60\u53ef\u4ee5\u5229\u7528\u65f6\u95f4\u53bb\u505a\u5f88\u591a\u4e8b\u60c5\uff0c\u6bd4\u8d77\u505a\u8fd9\u4e9b\u7c7b\u4f3c\u7684\u4f18\u5316\u8981\u597d\u5f97\u591a\u3002\u4e8b\u5b9e\u4e0a\uff0c\u6211\u5c55\u793a\u7ed9\u4f60\u770b\u7684\u4ee3\u7801\u5f88\u5c11\u6709\u4f18\u5316\u7684\u9700\u6c42\uff0c\u4ee5\u81f3\u4e8e\u6211\u5728 PayPal \u5de5\u4f5c\u76843\u5e74\u91cc\u4ece\u672a\u9700\u8981\u8fd9\u6837\u505a\uff0c\u751a\u81f3\u5728\u6211\u4f7f\u7528 React \u66f4\u957f\u7684\u65f6\u95f4\u91cc\u3002<\/p>\n<p>\u7136\u800c\uff0c\u6709\u4e9b\u60c5\u51b5\u4e0b\u6e32\u67d3\u53ef\u80fd\u4f1a\u82b1\u8d39\u5927\u91cf\u65f6\u95f4\uff08\u6bd4\u5982\u91cd\u4ea4\u4e92\u7684\u56fe\u8868\u3001\u52a8\u753b\u7b49\uff09\u3002\u591a\u4e8f React \u7684\u5b9e\u7528\u6027\uff0c\u6709\u4e00\u4e2a\u9003\u751f\u8231\uff08escape hatch\uff09\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kr\">const<\/span> <span class=\"nx\">CountButton<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">memo<\/span><span class=\"p\">(<\/span><span class=\"kd\">function<\/span> <span class=\"nx\">CountButton<\/span><span class=\"p\">({<\/span><span class=\"nx\">onClick<\/span><span class=\"p\">,<\/span> <span class=\"nx\">count<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">button<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">onClick<\/span><span class=\"p\">}&gt;{<\/span><span class=\"nx\">count<\/span><span class=\"p\">}&lt;\/<\/span><span class=\"nt\">button<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">})<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u73b0\u5728 React \u53ea\u4f1a\u5f53 <code>props<\/code> \u6539\u53d8\u65f6\u4f1a\u91cd\u65b0\u6e32\u67d3 <code>CountButton<\/code>\uff01  \u4f46\u6211\u4eec\u8fd8\u6ca1\u6709\u5b8c\u6210\uff0c\u8fd8\u8bb0\u5f97\u5f15\u7528\u76f8\u7b49\u5417\uff1f\u5728 <code>DualCounter<\/code> \u7ec4\u4ef6\u4e2d\uff0c\u6211\u4eec\u7ec4\u4ef6\u51fd\u6570\u91cc\u5b9a\u4e49\u4e86 <code>increment1<\/code> \u548c <code>increment2<\/code> \u51fd\u6570\uff0c\u8fd9\u610f\u5473\u7740\u6bcf\u6b21 <code>DualCounter<\/code> \u91cd\u65b0\u6e32\u67d3\uff0c\u90a3\u4e9b\u51fd\u6570\u4f1a\u65b0\u521b\u5efa\uff0c\u56e0\u6b64 React \u65e0\u8bba\u5982\u4f55\u4f1a\u91cd\u65b0\u6e32\u67d3\u4e24\u4e2a <code>CountButton<\/code>\u3002<\/p>\n<p>\u6240\u4ee5\u8fd9\u662f <code>useCallback<\/code> \u548c <code>useMemo<\/code> \u80fd\u6d3e\u4e0a\u7528\u573a\u7684\u53e6\u5916\u4e00\u4e2a\u573a\u666f\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kr\">const<\/span> <span class=\"nx\">CountButton<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">memo<\/span><span class=\"p\">(<\/span><span class=\"kd\">function<\/span> <span class=\"nx\">CountButton<\/span><span class=\"p\">({<\/span><span class=\"nx\">onClick<\/span><span class=\"p\">,<\/span> <span class=\"nx\">count<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">button<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">onClick<\/span><span class=\"p\">}&gt;{<\/span><span class=\"nx\">count<\/span><span class=\"p\">}&lt;\/<\/span><span class=\"nt\">button<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">})<\/span>\n\n<span class=\"kd\">function<\/span> <span class=\"nx\">DualCounter<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">count1<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setCount1<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">increment1<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useCallback<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">setCount1<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">),<\/span> <span class=\"p\">[])<\/span>\n\n  <span class=\"kr\">const<\/span> <span class=\"p\">[<\/span><span class=\"nx\">count2<\/span><span class=\"p\">,<\/span> <span class=\"nx\">setCount2<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useState<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">increment2<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useCallback<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">setCount2<\/span><span class=\"p\">(<\/span><span class=\"nx\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">c<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">),<\/span> <span class=\"p\">[])<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\n    <span class=\"p\">&lt;&gt;<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">CountButton<\/span> <span class=\"na\">count<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">count1<\/span><span class=\"p\">}<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">increment1<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n      <span class=\"p\">&lt;<\/span><span class=\"nt\">CountButton<\/span> <span class=\"na\">count<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">count2<\/span><span class=\"p\">}<\/span> <span class=\"na\">onClick<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nx\">increment2<\/span><span class=\"p\">}<\/span> <span class=\"p\">\/&gt;<\/span>\n    <span class=\"p\">&lt;\/&gt;<\/span>\n  <span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u73b0\u5728\u6211\u4eec\u53ef\u4ee5\u907f\u514d <code>CountButton<\/code> \u7684\u6240\u8c13\u201c\u4e0d\u5fc5\u8981\u7684\u91cd\u65b0\u6e32\u67d3\u201d\u3002<\/p>\n<p>\u6211\u60f3\u91cd\u7533\u4e0b\uff0c<strong>\u5728\u6ca1\u6709\u6d4b\u91cf\u524d<\/strong>\uff0c\u5f3a\u70c8\u5efa\u8bae\u4e0d\u8981\u4f7f\u7528 <code>React.momo<\/code> \uff08\u6216\u8005\u5b83\u7684\u670b\u53cb <code>PureComponent<\/code> \u548c <code>shouldComponentUpdate<\/code>\uff09\uff0c\u56e0\u4e3a\u4f18\u5316\u603b\u4f1a\u5e26\u6765\u6210\u672c\uff0c\u5e76\u4e14\u4f60\u9700\u8981\u786e\u4fdd\u77e5\u9053\u4f1a\u6709\u591a\u5c11\u6210\u672c\u548c\u6536\u76ca\uff0c\u8fd9\u6837\u4f60\u624d\u80fd\u51b3\u5b9a\u5728\u4f60\u7684\u6848\u4f8b\u4e2d\u5b83\u662f\u5426\u80fd\u771f\u7684\u6709\u5e2e\u52a9\uff08\u800c\u4e0d\u662f\u6709\u5bb3\u7684\uff09\u3002\u6b63\u5982\u6211\u4eec\u4e0a\u9762\u6240\u8bf4\u7684\u90a3\u6837\uff0c<strong>\u4e00\u76f4\u4fdd\u6301\u6b63\u786e\u662f\u4e00\u4ef6\u5f88\u56f0\u96be\u7684\u4e8b\u60c5\uff0c\u6240\u4ee5\u4f60\u53ef\u80fd\u65e0\u6cd5\u83b7\u5f97\u4efb\u4f55\u597d\u5904<\/strong>\u3002<\/p>\n<h2 id=\"\u6602\u8d35\u7684\u8ba1\u7b97\">\u6602\u8d35\u7684\u8ba1\u7b97<\/h2>\n<p>\u8fd9\u662f <code>useMemo<\/code> \u5185\u7f6e\u4e8e React \u7684\u53e6\u4e00\u4e2a\u539f\u56e0\uff08\u6ce8\u610f\u8fd9\u4e2a\u4e0d\u9002\u7528\u4e8e <code>useCallback<\/code>\uff09\u3002<code>useMemo<\/code> \u7684\u597d\u5904\u662f\u4f60\u53ef\u4ee5\u91c7\u7528\u5982\u4e0b\u503c\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><span class=\"nx\">b<\/span><span class=\"o\">:<\/span> <span class=\"nx\">props<\/span><span class=\"p\">.<\/span><span class=\"nx\">b<\/span><span class=\"p\">}<\/span>\n\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u7136\u540e\u60f0\u6027\u83b7\u53d6\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useMemo<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">({<\/span><span class=\"nx\">b<\/span><span class=\"o\">:<\/span> <span class=\"nx\">props<\/span><span class=\"p\">.<\/span><span class=\"nx\">b<\/span><span class=\"p\">}),<\/span> <span class=\"p\">[<\/span><span class=\"nx\">props<\/span><span class=\"p\">.<\/span><span class=\"nx\">b<\/span><span class=\"p\">])<\/span>\n\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8fd9\u5bf9\u4e8e\u4e0a\u9762\u7684\u60c5\u51b5\u5e76\u4e0d\u662f\u5f88\u6709\u7528\uff0c\u4f46\u662f\u60f3\u8c61\u4e00\u4e0b\u4f60\u6709\u4e00\u4e2a\u8ba1\u7b97\u6210\u672c\u5f88\u9ad8\u7684\u540c\u6b65\u8ba1\u7b97\u503c\u7684\u51fd\u6570\uff08\u6211\u7684\u610f\u601d\u662f\u6709\u591a\u5c11\u5e94\u7528\u771f\u5b9e\u5730\u9700\u8981 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Tools\/Performance\/Scenarios\/Intensive_JavaScript\">\u50cf\u8fd9\u6837\u8ba1\u7b97\u7d20\u6570<\/a>\uff0c\u4f46\u8fd9\u5c31\u662f\u4e00\u4e2a\u4f8b\u5b50\uff09\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kd\">function<\/span> <span class=\"nx\">RenderPrimes<\/span><span class=\"p\">({<\/span><span class=\"nx\">iterations<\/span><span class=\"p\">,<\/span> <span class=\"nx\">multiplier<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">primes<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">calculatePrimes<\/span><span class=\"p\">(<\/span><span class=\"nx\">iterations<\/span><span class=\"p\">,<\/span> <span class=\"nx\">multiplier<\/span><span class=\"p\">)<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span><span class=\"nx\">Primes<\/span><span class=\"o\">!<\/span> <span class=\"p\">{<\/span><span class=\"nx\">primes<\/span><span class=\"p\">}&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">}<\/span>\n\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u4f7f\u7528\u6b63\u786e\u7684 <code>iterations<\/code> \u6216 <code>multiplier<\/code> \u53ef\u80fd\u4f1a\u975e\u5e38\u7f13\u6162\uff0c\u800c\u4e14\u4f60\u6ca1\u6709\u592a\u591a\u53ef\u4ee5\u7279\u522b\u505a\u7684\u4e8b\u60c5\u3002\u4f60\u4e0d\u80fd\u81ea\u52a8\u5730\u7528\u6237\u7684\u786c\u4ef6\u66f4\u5feb\uff0c\u4f46\u662f\u4f60\u53ef\u4ee5\u8fd9\u6837\u505a\uff0c\u8fd9\u6837\u4f60\u5c31\u4e0d\u5fc5\u8fde\u7eed\u4e24\u6b21\u8ba1\u7b97\u76f8\u540c\u7684\u503c\uff0c\u8fd9\u5c31\u662f <code>useMemo<\/code> \u4e3a\u4f60\u6240\u505a\u7684\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-react\" data-lang=\"react\"><span class=\"kd\">function<\/span> <span class=\"nx\">RenderPrimes<\/span><span class=\"p\">({<\/span><span class=\"nx\">iterations<\/span><span class=\"p\">,<\/span> <span class=\"nx\">multiplier<\/span><span class=\"p\">})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">primes<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">React<\/span><span class=\"p\">.<\/span><span class=\"nx\">useMemo<\/span><span class=\"p\">(()<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"nx\">calculatePrimes<\/span><span class=\"p\">(<\/span><span class=\"nx\">iterations<\/span><span class=\"p\">,<\/span> <span class=\"nx\">multiplier<\/span><span class=\"p\">),<\/span> <span class=\"p\">[<\/span>\n    <span class=\"nx\">iterations<\/span><span class=\"p\">,<\/span>\n    <span class=\"nx\">multiplier<\/span><span class=\"p\">,<\/span>\n  <span class=\"p\">])<\/span>\n  <span class=\"k\">return<\/span> <span class=\"p\">&lt;<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span><span class=\"nx\">Primes<\/span><span class=\"o\">!<\/span> <span class=\"p\">{<\/span><span class=\"nx\">primes<\/span><span class=\"p\">}&lt;\/<\/span><span class=\"nt\">div<\/span><span class=\"p\">&gt;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u53ef\u4ee5\u8fd9\u6837\u505a\u7684\u539f\u56e0\u662f\uff0c\u5373\u4f7f\u4f60\u5728\u6bcf\u6b21\u6e32\u67d3\u65f6\u5b9a\u4e49\u4e86\u8ba1\u7b97\u7d20\u6570\u7684\u51fd\u6570\uff08\u975e\u5e38\u5feb\uff09\uff0cReact\u53ea\u5728\u9700\u8981\u503c\u65f6\u624d\u8c03\u7528\u8be5\u51fd\u6570\u3002 \u9664\u6b64\u4e4b\u5916\uff0cReact\u8fd8\u4f1a\u5728\u7ed9\u5b9a\u8f93\u5165\u7684\u60c5\u51b5\u4e0b\u5b58\u50a8\u5148\u524d\u7684\u503c\uff0c\u5e76\u5728\u7ed9\u5b9a\u8ddf\u4e4b\u524d\u76f8\u540c\u8f93\u5165\u7684\u60c5\u51b5\u4e0b\u8fd4\u56de\u5148\u524d\u7684\u503c\u3002 \u8fd9\u662f <strong>memoization<\/strong> \u5728\u8d77\u4f5c\u7528\u3002<\/p>\n<h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2>\n<p>\u6700\u540e\uff0c\u6211\u60f3\u8bf4\uff0c\u6bcf\u4e2a\u62bd\u8c61(\u548c\u6027\u80fd\u4f18\u5316)\u90fd\u662f\u6709\u4ee3\u4ef7\u7684\u3002\u5e94\u7528 <a href=\"https:\/\/kentcdodds.com\/blog\/aha-programming\">AHA \u7f16\u7a0b\u539f\u5219<\/a>\uff0c\u76f4\u5230\u786e\u5b9e\u9700\u8981\u62bd\u8c61\u6216\u4f18\u5316\u65f6\u624d\u53bb\u505a\uff0c\u8fd9\u6837\u53ef\u4ee5\u907f\u514d\u627f\u62c5\u6210\u672c\u800c\u4e0d\u4f1a\u83b7\u5f97\u6536\u76ca\u7684\u60c5\u51b5\u3002<\/p>\n<p>\u5177\u4f53\u6765\u8bf4\uff0c<code>useCallback<\/code> \u548c <code>useMemo<\/code>\u7684\u6210\u672c\u662f\uff1a\u5bf9\u4e8e\u4f60\u7684\u540c\u4e8b\u6765\u8bf4\uff0c\u4f60\u4f7f\u4ee3\u7801\u66f4\u590d\u6742\u4e86\uff1b\u4f60\u53ef\u80fd\u5728\u4f9d\u8d56\u9879\u6570\u7ec4\u4e2d\u72af\u4e86\u4e00\u4e2a\u9519\u8bef\uff0c\u5e76\u4e14\u4f60\u53ef\u80fd\u901a\u8fc7\u8c03\u7528\u5185\u7f6e\u7684 hook\u3001\u5e76\u9632\u6b62\u4f9d\u8d56\u9879\u548c memoized \u503c\u88ab\u5783\u573e\u6536\u96c6\uff0c\u800c\u4f7f\u6027\u80fd\u53d8\u5dee\u3002\u5982\u679c\u4f60\u83b7\u5f97\u4e86\u5fc5\u8981\u7684\u6027\u80fd\u6536\u76ca\uff0c\u90a3\u4e48\u8fd9\u4e9b\u6210\u672c\u90fd\u662f\u503c\u5f97\u627f\u62c5\u7684\uff0c\u4f46<strong>\u6700\u597d\u5148\u6d4b\u91cf\u4e00\u4e0b<\/strong>\u3002<\/p>\n<p>\u76f8\u5173\u9605\u8bfb\uff1a<\/p>\n<ul>\n<li>React FAQ: <a href=\"https:\/\/reactjs.org\/docs\/hooks-faq.html#are-hooks-slow-because-of-creating-functions-in-render\">&ldquo;Are Hooks slow because of creating functions in render?&quot;<\/a><\/li>\n<li><a href=\"https:\/\/twitter.com\/ryanflorence\">Ryan Florence<\/a>: <a href=\"https:\/\/reacttraining.com\/blog\/react-inline-functions-and-performance\">React, Inline Functions, and Performance<\/a><\/li>\n<\/ul>"},{"title":"Node Cluster Workers IPC","link":"https:\/\/jancat.github.io\/post\/2019\/node-cluster-workers-ipc\/","pubDate":"Thu, 27 Jun 2019 00:50:07 +0800","guid":"https:\/\/jancat.github.io\/post\/2019\/node-cluster-workers-ipc\/","description":"<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190627003616.png\" alt=\"\"><\/p>\n<p>Node \u4ee5\u5355\u8fdb\u7a0b\u3001JS \u5355\u7ebf\u7a0b\u67b6\u6784\u8fd0\u884c\u65f6\uff0c\u7531\u4e8e\u5176\u5f02\u6b65\u975e\u963b\u585e\u3001\u4e8b\u4ef6\u9a71\u52a8\u7684\u7279\u6027\uff0c\u80fd\u591f\u540c\u65f6\u63a5\u53d7\u5927\u91cf\u5e76\u53d1\u8bf7\u6c42\uff0cI\/O \u7ebf\u7a0b\u201c\u63a5\u5355\u201d\u540e\u653e\u5165\u4e8b\u4ef6\u961f\u5217\u4e2d\u7b49\u7740\u88ab\u4e8b\u4ef6\u5faa\u73af\u5904\u7406\u3002<\/p>\n<h2 id=\"\u5355\u8fdb\u7a0b\u5355\u7ebf\u7a0b\u7684\u5c40\u9650\u548c-cluster-\u7684\u4f18\u52bf\">\u5355\u8fdb\u7a0b\u5355\u7ebf\u7a0b\u7684\u5c40\u9650\u548c Cluster \u7684\u4f18\u52bf<\/h2>\n<p>\u7136\u800c\uff0c\u5355\u8fdb\u7a0b\u4e0b\u65e0\u6cd5\u5145\u5206\u5229\u7528\u591a\u6838 CPU \u7684\u8ba1\u7b97\u80fd\u529b\uff0c\u9020\u6210\u8d44\u6e90\u6d6a\u8d39\uff0c\u800c\u4e14\u5e76\u53d1\u6570\u9010\u6e10\u589e\u52a0\u540e\uff0c\u6bcf\u4e2a\u8bf7\u6c42\u7684\u5e73\u5747\u5904\u7406\u65f6\u95f4\u4f1a\u8d8a\u6765\u8d8a\u957f\u3002\u8fd9\u4e2a\u9636\u6bb5\u6027\u80fd\u8fd8\u662f\u6bd4\u8f83\u5bb9\u6613\u63d0\u5347\u7684\uff0c\u53ef\u4ee5\u5f15\u5165 Node Cluster\uff0c\u7528\u96c6\u7fa4\u591a\u8fdb\u7a0b\u7684\u65b9\u5f0f\u5145\u5206\u5229\u7528\u591a\u6838 CPU\u3002<\/p>\n<p><a href=\"https:\/\/medium.com\/tech-tajawal\/clustering-in-nodejs-utilizing-multiple-processor-cores-75d78aeb0f4f\">Clustering in NodeJs\u200a\u2014\u200aPerformance Optimization\u200a\u2014\u200aPart I<\/a> \u4e00\u6587\u4e2d\u5bf9\u5355\u7ebf\u7a0b\uff08\u8fdb\u7a0b\uff09\u548c Cluster \u96c6\u7fa4\uff0c\u591a\u4e2a\u5e76\u53d1\u8bf7\u6c42\u91cf\u4e0b\u7684\u5e73\u5747\u5904\u7406\u65f6\u95f4\u505a\u4e86\u6d4b\u8bd5\u6bd4\u8f83\uff0c\u6d4b\u8bd5\u6570\u636e\u5982\u4e0b\u56fe\u3002\u7ed3\u679c\u8868\u660e\uff0c\u5728 Cluster \u96c6\u7fa4\u4e0b\uff0c\u6027\u80fd\uff08\u8bf7\u6c42\u5e73\u5747\u5904\u7406\u65f6\u95f4\uff09\u63d0\u5347\u4e86 66%\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190623195156.png\" alt=\"\"><\/p>\n<h2 id=\"cluster-\u5b9e\u8df5\">Cluster \u5b9e\u8df5<\/h2>\n<blockquote>\n<p>cluster \u6a21\u578b\u4e0b\uff0cmaster \u79f0\u4e3a\u4e3b\u8fdb\u7a0b\uff0cfork \u51fa\u6765\u7684 worker \u5373\u4ece\u8fdb\u7a0b<\/p>\n<\/blockquote>\n<p>\u7b80\u5355\u7684 master - worker \u6a21\u578b\u5904\u7406 http \u8bf7\u6c42\u7684\u4f8b\u5b50\uff1a<\/p>\n<p><strong>master.js<\/strong><\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">cluster<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;cluster&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">numCPUs<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;os&#39;<\/span><span class=\"p\">).<\/span><span class=\"nx\">cpus<\/span><span class=\"p\">().<\/span><span class=\"nx\">length<\/span>\n\n<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">isMaster<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Master <\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> is running`<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"c1\">\/\/ Fork workers.\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kd\">let<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">numCPUs<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span><span class=\"o\">++<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">fork<\/span><span class=\"p\">()<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;exit&#39;<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">worker<\/span><span class=\"p\">,<\/span> <span class=\"nx\">code<\/span><span class=\"p\">,<\/span> <span class=\"nx\">signal<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`worker <\/span><span class=\"si\">${<\/span><span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> died`<\/span><span class=\"p\">)<\/span>\n    <span class=\"c1\">\/\/ accidental exit, add new worker\n<\/span><span class=\"c1\"><\/span>    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">exitedAfterDisconnect<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">fork<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;.\/worker&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5f15\u5165\u4e86 <code>cluster<\/code> \u6a21\u5757\u540e\uff0c\u6839\u636e <code>cluster.isMaster<\/code> \u5224\u65ad\u5f53\u524d\u8fdb\u7a0b\u662f\u5426\u4e3b\u8fdb\u7a0b\uff0c\u7136\u540e <strong>fork<\/strong> \u51fa worker\uff0c\u4e00\u822c\u6839\u636e CPU \u6570\u91cf\u6765\u51b3\u5b9a worker \u6570\u91cf\u3002\u5982\u679c\u662f worker\uff0c\u5219\u5f15\u5165 worker \u6587\u4ef6\u6267\u884c\u3002\u8fd9\u91cc\u628a master \u548c worker \u6a21\u5757\u5206\u79bb\u5f00\u6765\uff0c\u65b9\u4fbf\u5355\u72ec\u7ef4\u62a4\u3002<\/p>\n<p>\u4f7f\u7528 <code>if else<\/code> \u6761\u4ef6\u5206\u652f\u662f\u56e0\u4e3a\u6267\u884c <code>fork()<\/code> \u4e4b\u540e\uff0cworker \u4f1a\u4ee5\u65b0\u8fdb\u7a0b\u7684\u65b9\u5f0f\u91cd\u65b0\u6267\u884c\u5f53\u524d\u6587\u4ef6\uff0c\u6240\u4ee5\u9700\u8981\u6839\u636e\u5f53\u524d\u8fdb\u7a0b\u7c7b\u578b\u6267\u884c\u5bf9\u5e94\u7684\u903b\u8f91\u3002<\/p>\n<p>master \u4e2d\u8fd8\u76d1\u542c\u4e86 worker <code>exit<\/code> \u4e8b\u4ef6\uff0c\u5f53 worker \u5f02\u5e38\u9000\u51fa\uff08\u975e master \u4e3b\u52a8\u5173\u95ed\uff0c\u901a\u8fc7 <code>exitedAfterDisconnect<\/code> \u5224\u65ad\uff09\u65f6\uff0c\u518d\u91cd\u65b0 fork \u4e00\u4e2a worker\u3002<\/p>\n<p><strong>worker.js<\/strong><\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">http<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;http&#39;<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\">\/\/ Workers can share any TCP connection\n<\/span><span class=\"c1\">\/\/ In this case it is an HTTP server\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">http<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">createServer<\/span><span class=\"p\">((<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeHead<\/span><span class=\"p\">(<\/span><span class=\"mi\">200<\/span><span class=\"p\">)<\/span>\n    <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">end<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;hello world\\n&#39;<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">})<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">listen<\/span><span class=\"p\">(<\/span><span class=\"mi\">8000<\/span><span class=\"p\">)<\/span>\n\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Worker <\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> started`<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>worker \u4e2d\u8d1f\u8d23\u5904\u7406 HTTP \u8bf7\u6c42\u548c\u54cd\u5e94\uff0c\u867d\u7136 listen \u540c\u4e00\u4e2a\u7aef\u53e3\uff0c\u4f46\u5176\u5b9e\u662f\u53ea\u6709 master \u76d1\u542c\u4e86\u8be5\u7aef\u53e3\uff0c\u6709\u65b0\u7684\u8fde\u63a5\u8fc7\u6765\u540e\u5206\u914d\u7ed9 workers \u5904\u7406\u3002<\/p>\n<h2 id=\"cluster-workers-ipc\">Cluster workers IPC<\/h2>\n<p>master \u548c worker \u4e4b\u95f4\u53ef\u4ee5\u5229\u7528 IPC \u901a\u9053\u8fdb\u884c\u901a\u4fe1\uff0c\u901a\u8fc7 <code>process.send()<\/code> \u548c <code>process.on('message')<\/code> \u5728 master \u548c worker \u95f4\u4f20\u9012\u6d88\u606f\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ worker\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;message&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Message from parent:&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">})<\/span>\n<span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">send<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Message from worker&#39;<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><img src=\"http:\/\/zhenhua-lee.github.io\/img\/node-server\/process.png\" alt=\"\u00e5\u00a4\u009a\u00e6 \u00b8\u00e5\u0088\u00a9\u00e7\u0094\u00a8\"><\/p>\n<p>\u4f46\u662f\u8fd9\u4e2a IPC \u901a\u9053\u53ea\u5b58\u5728\u4e8e\u7236\u5b50\u8fdb\u7a0b\u4e4b\u95f4\uff0c\u662f\u7531 libuv \u521b\u5efa\u7684\uff0cworkers \u4e4b\u95f4\u5982\u679c\u8981 IPC \u8be5\u600e\u4e48\u529e\u5462\uff1f\u56e0\u4e3a workers \u4e0d\u9002\u5408\u81ea\u5df1\u6765\u5b9e\u73b0 IPC \u4e92\u76f8\u901a\u4fe1\uff0c\u8c01\u6765\u8fde\u63a5\u8c01\u5462\uff1f\u6240\u4ee5\u6700\u597d\u662f\u901a\u8fc7\u4e00\u4e2a\u4ee3\u7406\u6765\u5b9e\u73b0\u3002workers \u8fde\u63a5\u4ee3\u7406\uff0c\u4e0e\u4ee3\u7406\u4e92\u76f8\u53d1\u9001\u548c\u63a5\u6536\u6d88\u606f\uff0c\u4ee3\u7406\u53ea\u8d1f\u8d23\u8f6c\u53d1\uff0c\u8fd9\u6837\u5c31\u80fd\u8fbe\u5230 workers \u4e4b\u95f4 IPC \u7684\u76ee\u7684\u3002<\/p>\n<p>\u4e0b\u9762\u4ecb\u7ecd\u4e24\u79cd\u65b9\u5f0f\u6765\u5b9e\u73b0\u8fd9\u4e2a\u4ee3\u7406\uff1a<\/p>\n<h3 id=\"unix-domain-socket-ipc\">Unix Domain Socket IPC<\/h3>\n<p>\u901a\u8fc7 Node <code>net.createServer()<\/code> \u53ef\u4ee5\u521b\u5efa Unix domain socket server\uff0c\u76d1\u542c\u672c\u5730\u6587\u4ef6\u53e5\u67c4\u6765\u5b9e\u73b0\u672c\u5730\u8de8\u8fdb\u7a0b\u901a\u4fe1\u3002Unix domain socket server \u5f00\u59cb\u76d1\u542c\u540e\uff0cwrokers \u901a\u8fc7 <code>net.connect()<\/code> \u521b\u5efa client socket \u8fde\u63a5\u5230 server socket\uff0cUnix domain socket \u662f\u5168\u53cc\u5de5\u7684\uff0c\u56e0\u6b64\u53cc\u65b9\u90fd\u53ef\u4ee5\u4f7f\u7528<code>send()<\/code>\u548c<code>recv()<\/code>\u6765\u8fdb\u884c\u6570\u636e\u7684\u6536\u53d1\u3002<\/p>\n<blockquote>\n<p>\u60f3\u6df1\u5165\u4e86\u89e3 net \u548c Unix domain socket \u63a8\u8350\u9605\u8bfb\uff1a<\/p>\n<p><a href=\"https:\/\/cnodejs.org\/topic\/5ae1f5da39a81e4548f45741\">\u4e00\u4e2a\u4f7f\u7528 unix domain socket \u8fdb\u884c IPC \u7684\u5c0f\u4f8b\u5b50<\/a><\/p>\n<p><a href=\"https:\/\/semlinker.com\/node-net\/\">\u6df1\u5165\u5b66\u4e60 Node.js Net<\/a><\/p>\n<\/blockquote>\n<p>\u67d0\u4e2a worker \u60f3\u8981\u8ddf\u5176\u5b83 worker \u540c\u6b65\u6570\u636e\u65f6\uff0c\u9996\u5148\u8c03\u7528 <code>send()<\/code> \u53d1\u9001\u6570\u636e\u7ed9 server socket\uff0cserver socket \u901a\u8fc7 <code>recv()<\/code> \u63a5\u6536\u5230\u6d88\u606f\u540e\u8f6c\u53d1\u5230\u5bf9\u5e94\u7684 workers\uff0c\u5b9e\u73b0\u4e86 workers \u6570\u636e\u540c\u6b65\u3002<\/p>\n<p>\u8ddf master - worker \u63d0\u4f9b\u7684 IPC API \u4e0d\u540c\uff0c\u8fd9\u79cd\u65b9\u5f0f\u9700\u8981\u6211\u4eec\u81ea\u5df1\u5b9e\u73b0 Node IPC \u7684\u7ec6\u8282\uff0c\u7ba1\u7406\u6570\u636e\u901a\u4fe1\uff0c\u6210\u672c\u8f83\u9ad8\u3002<\/p>\n<p><a href=\"https:\/\/midwayjs.org\/pandora\/zh-cn\/guide\/process\/ipc_hub.html#%E7%9B%B4%E6%8E%A5%E5%8F%91%E5%B8%83%E5%AF%B9%E8%B1%A1%E5%92%8C%E8%8E%B7%E5%8F%96%E5%AF%B9%E8%B1%A1%E4%BB%A3%E7%90%86\">Pandora.js \u8fdb\u7a0b\u95f4\u901a\u4fe1<\/a> \u5c31\u662f\u4f7f\u7528\u4e86 Unix Domain Socket IPC \u6765\u5b9e\u73b0\u8de8\u8fdb\u7a0b\u8bbf\u95ee\u3001\u8c03\u7528\u3002<\/p>\n<blockquote>\n<p>Pandora.js \u521b\u5efa Unix Domain Socket \u7684\u6e90\u7801\uff1a<\/p>\n<p><a href=\"https:\/\/github.com\/midwayjs\/pandora\/blob\/f9089637c15f6a3070cc601abb7744bc42f229aa\/packages\/messenger\/src\/base.ts#L37\">Pandora messenger base<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/midwayjs\/pandora\/blob\/f9089637c15f6a3070cc601abb7744bc42f229aa\/packages\/messenger\/src\/server.ts#L28\">Pandora messenger server<\/a><\/p>\n<\/blockquote>\n<p>\u8fd8\u6709 <a href=\"https:\/\/github.com\/RIAEvangelist\/node-ipc\">node-ipc<\/a> \u8fd9\u4e2a node \u6a21\u5757\u5c01\u88c5\u4e86\u901a\u7528\u7684 IPC API\uff0c\u867d\u7136\u4e0d\u518d\u7ef4\u62a4\u4e86\uff0c\u4f46\u4e0b\u8f7d\u91cf\u633a\u9ad8\u7684\uff0c\u4e0d\u59a8\u4e00\u8bd5\u3002<\/p>\n<h3 id=\"master-\u4ee3\u7406\">Master \u4ee3\u7406<\/h3>\n<p>Unix domain socket \u5b9e\u73b0 IPC \u4e13\u804c\u8d1f\u8d23 workers IPC \u4ee3\u7406\uff0c\u867d\u7136\u81ea\u7531\u5ea6\u66f4\u9ad8\uff0c\u80fd\u7075\u6d3b\u63a7\u5236 IPC \u7ec6\u8282\uff0c\u4f46\u76f8\u5e94\u7684\u4f1a\u589e\u52a0\u5f00\u53d1\u7ef4\u62a4\u6210\u672c\u3002\u5982\u679c\u53ea\u9700\u8981\u7b80\u5355\u7684 workers IPC \uff0c\u5b8c\u5168\u53ef\u4ee5\u8ba9 master \u4ee3\u7406\uff0c\u901a\u8fc7 master - worker IPC \u63d0\u4f9b\u7684 API \u5feb\u901f\u5b9e\u73b0\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190627010404.png\" alt=\"\"><\/p>\n<p><strong>Egg.js<\/strong> <a href=\"https:\/\/eggjs.org\/zh-cn\/core\/cluster-and-ipc.html\">\u8fdb\u7a0b\u95f4\u901a\u4fe1<\/a>\u4e5f\u4ecb\u7ecd\u4e86\u8fd9\u79cd\u65b9\u5f0f\uff0c\u5982\u679c\u60f3\u8981\u5728\u6240\u6709 workers \u4e4b\u95f4\u540c\u6b65\uff0c\u53ef\u4ee5\u901a\u8fc7 <strong>Agent<\/strong> \u6765\u5e7f\u64ad\uff0c\u5982\u679c\u60f3\u8981\u5728\u6307\u5b9a\u7684 workers \u95f4\u901a\u4fe1\uff0c\u5c31\u901a\u8fc7 master \u6765\u8f6c\u53d1\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\">\u5e7f\u64ad\u6d88\u606f\uff1a agent =&gt; all workers\n                  +--------+          +-------+\n                  | Master |&lt;---------| Agent |\n                  +--------+          +-------+\n                 \/    |     \\\n                \/     |      \\\n               \/      |       \\\n              \/       |        \\\n             v        v         v\n  +----------+   +----------+   +----------+\n  | Worker 1 |   | Worker 2 |   | Worker 3 |\n  +----------+   +----------+   +----------+\n\n\u6307\u5b9a\u63a5\u6536\u65b9\uff1a one worker =&gt; another worker\n                  +--------+          +-------+\n                  | Master |----------| Agent |\n                  +--------+          +-------+\n                 ^    |\n     send to    \/     |\n    worker 2   \/      |\n              \/       |\n             \/        v\n  +----------+   +----------+   +----------+\n  | Worker 1 |   | Worker 2 |   | Worker 3 |\n  +----------+   +----------+   +----------+\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"ip-\u9650\u6d41\u4f8b\u5b50\">IP \u9650\u6d41\u4f8b\u5b50<\/h4>\n<p>\u73b0\u5728\u901a\u8fc7 Master \u4ee3\u7406\u7684\u65b9\u5f0f\u6765\u5b9e\u73b0\u4e00\u4e2a Cluster \u6a21\u5f0f\u4e0b IP \u9650\u6d41\u7684\u4f8b\u5b50\uff0c\u76ee\u7684\u662f\u5728 workers \u95f4\u5bf9\u540c\u4e00\u4e2a IP \u7684\u8bf7\u6c42\u6b21\u6570\u505a\u9650\u5236\uff0c\u8d85\u8fc7\u8bf7\u6c42\u9608\u503c\u540e\u5c31\u54cd\u5e94\u9519\u8bef\u3002\u8fd9\u5c31\u8981\u6c42 workers \u95f4\u540c\u6b65\u6bcf\u4e2a IP \u7684\u8bf7\u6c42\u6b21\u6570\uff0c\u8fd9\u91cc\u901a\u8fc7 master \u6765\u4ee3\u7406 workers IPC\u3002<\/p>\n<h5 id=\"workerjs\">worker.js<\/h5>\n<p>worker \u4f1a\u5728\u5904\u7406\u8bf7\u6c42\u65f6\u8bb0\u5f55\u5f53\u524d\u7684 IP\uff0c\u5e76\u5411 master \u53d1\u9001\u6d88\u606f\u540c\u6b65\u7ed9\u5176\u5b83 workers\uff0c\u5982\u679c\u5f53\u524d IP \u7684\u7d2f\u8ba1\u8bf7\u6c42\u6570\u91cf\u8d85\u8fc7\u9608\u503c\uff0c\u5219\u54cd\u5e94 400\u3002<\/p>\n<p>worker \u4f1a\u76d1\u542c master \u7684 <code>message<\/code> \u6d88\u606f\uff0c\u5f53\u63a5\u6536\u5230\u5176\u5b83 workers \u53d1\u6765\u7684 IP \u540c\u6b65\u6d88\u606f\u65f6\uff0c\u5c31\u589e\u52a0\u5f53\u524d\u8fdb\u7a0b\u8bb0\u5f55\u7684 IP \u8bf7\u6c42\u6570\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><span class=\"lnt\">36\n<\/span><span class=\"lnt\">37\n<\/span><span class=\"lnt\">38\n<\/span><span class=\"lnt\">39\n<\/span><span class=\"lnt\">40\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">http<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;http&#39;<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\">\/\/ record the number of IP requests\n<\/span><span class=\"c1\"><\/span><span class=\"kr\">const<\/span> <span class=\"nx\">ipRecord<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">MAX_REQUEST<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">3<\/span>\n\n<span class=\"c1\">\/\/ Workers can share any TCP connection\n<\/span><span class=\"c1\">\/\/ In this case it is an HTTP server\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">http<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">createServer<\/span><span class=\"p\">((<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">realIP<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;x-forwarded-for&#39;<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">connection<\/span><span class=\"p\">.<\/span><span class=\"nx\">remoteAddress<\/span>\n\n    <span class=\"nx\">realIP<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">syncRequest<\/span><span class=\"p\">(<\/span><span class=\"nx\">realIP<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">realIP<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">realIP<\/span><span class=\"p\">]<\/span> <span class=\"o\">&gt;<\/span> <span class=\"nx\">MAX_REQUEST<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">warn<\/span><span class=\"p\">(<\/span><span class=\"sb\">`[<\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\">] IP: <\/span><span class=\"si\">${<\/span><span class=\"nx\">realIP<\/span><span class=\"si\">}<\/span><span class=\"sb\"> exceeded the maximum request quantity!`<\/span><span class=\"p\">)<\/span>\n      <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeHead<\/span><span class=\"p\">(<\/span><span class=\"mi\">400<\/span><span class=\"p\">).<\/span><span class=\"nx\">end<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Too many requests!&#39;<\/span><span class=\"p\">)<\/span>\n      <span class=\"k\">return<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeHead<\/span><span class=\"p\">(<\/span><span class=\"mi\">200<\/span><span class=\"p\">).<\/span><span class=\"nx\">end<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;hello world\\n&#39;<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">})<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">listen<\/span><span class=\"p\">(<\/span><span class=\"mi\">8000<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\">\/\/ increase ip request number when notified by other workers\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;message&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">message<\/span><span class=\"p\">.<\/span><span class=\"nx\">action<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;SYNC_REQUEST&#39;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">message<\/span><span class=\"p\">.<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">message<\/span><span class=\"p\">.<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">})<\/span>\n\n<span class=\"c1\">\/\/ increase ip request number and notify other workers\n<\/span><span class=\"c1\"><\/span><span class=\"kd\">function<\/span> <span class=\"nx\">syncRequest<\/span><span class=\"p\">(<\/span><span class=\"nx\">ip<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n  <span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">send<\/span><span class=\"p\">({<\/span>\n    <span class=\"nx\">action<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;SYNC_REQUEST&#39;<\/span><span class=\"p\">,<\/span>\n    <span class=\"nx\">ip<\/span><span class=\"p\">,<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Worker <\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> started`<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h5 id=\"masterjs\">master.js<\/h5>\n<p>master \u5728 fork worker \u540e\u540c\u65f6\u76d1\u542c\u4e86\u8be5 worker \u7684 <code>message<\/code> \u6d88\u606f\uff0c\u5f53\u4e00\u4e2a worker \u5e0c\u671b\u8ddf\u5176\u5b83 workers \u540c\u6b65 IP \u8bf7\u6c42\u65f6\uff0cmaster \u4f1a\u8d1f\u8d23\u5c06\u6d88\u606f\u8f6c\u53d1\u7ed9\u5176\u5b83 workers\uff0c\u8fbe\u5230\u4e86 workers IPC \u7684\u76ee\u7684\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">cluster<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;cluster&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">numCPUs<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;os&#39;<\/span><span class=\"p\">).<\/span><span class=\"nx\">cpus<\/span><span class=\"p\">().<\/span><span class=\"nx\">length<\/span>\n\n<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">isMaster<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Master <\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> is running`<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"c1\">\/\/ Fork workers.\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kd\">let<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">numCPUs<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span><span class=\"o\">++<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">worker<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">fork<\/span><span class=\"p\">()<\/span>\n    <span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;message&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"c1\">\/\/ proxy workers IPC\n<\/span><span class=\"c1\"><\/span>      <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">message<\/span><span class=\"p\">.<\/span><span class=\"nx\">action<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;SYNC_REQUEST&#39;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">sendToOhterWorkers<\/span><span class=\"p\">(<\/span><span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span><span class=\"p\">)<\/span>\n      <span class=\"p\">}<\/span>\n    <span class=\"p\">})<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;exit&#39;<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">worker<\/span><span class=\"p\">,<\/span> <span class=\"nx\">code<\/span><span class=\"p\">,<\/span> <span class=\"nx\">signal<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`worker <\/span><span class=\"si\">${<\/span><span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> died`<\/span><span class=\"p\">)<\/span>\n    <span class=\"c1\">\/\/ accidental exit, add new worker\n<\/span><span class=\"c1\"><\/span>    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">exitedAfterDisconnect<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">fork<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">})<\/span>\n\n  <span class=\"kd\">function<\/span> <span class=\"nx\">sendToOhterWorkers<\/span><span class=\"p\">(<\/span><span class=\"nx\">workerSender<\/span><span class=\"p\">,<\/span> <span class=\"nx\">message<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kr\">const<\/span> <span class=\"nx\">id<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">workers<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">+<\/span><span class=\"nx\">id<\/span> <span class=\"o\">!==<\/span> <span class=\"nx\">workerSender<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">workers<\/span><span class=\"p\">[<\/span><span class=\"nx\">id<\/span><span class=\"p\">].<\/span><span class=\"nx\">send<\/span><span class=\"p\">(<\/span><span class=\"nx\">message<\/span><span class=\"p\">)<\/span>\n      <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;.\/worker&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h5 id=\"\u6d4b\u8bd5\">\u6d4b\u8bd5<\/h5>\n<p>\u542f\u52a8 <strong>master.js<\/strong>\uff0cworkers \u5f00\u59cb\u76d1\u542c\u672c\u5730 8000 \u7aef\u53e3 HTTP \u8bf7\u6c42\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">node master.js\nMaster <span class=\"m\">63657<\/span> is running\nWorker <span class=\"m\">63658<\/span> started\nWorker <span class=\"m\">63659<\/span> started\nWorker <span class=\"m\">63660<\/span> started\n...\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u4f7f\u7528 <code>curl<\/code> \u547d\u4ee4\u8bbe\u7f6e <code>X-Forwarded-For<\/code> header\uff0c\u6a21\u62df\u4e0d\u540c IP \u8bf7\u6c42\u3002\u9996\u5148\u6a21\u62df <code>0.0.0.0<\/code> IP \u8fde\u7eed\u53d1\u9001 3 \u6b21\u8bf7\u6c42\uff0c\u8bf7\u6c42\u9608\u503c\u8bbe\u7f6e\u4e3a 3\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">curl --header <span class=\"s2\">&#34;X-Forwarded-For: 0.0.0.0&#34;<\/span> -i localhost:8000\ncurl --header <span class=\"s2\">&#34;X-Forwarded-For: 0.0.0.0&#34;<\/span> -i localhost:8000\ncurl --header <span class=\"s2\">&#34;X-Forwarded-For: 0.0.0.0&#34;<\/span> -i localhost:8000\n\nHTTP\/1.1 <span class=\"m\">200<\/span> OK\nhello world\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>IP <code>0.0.0.0<\/code> \u53d1\u9001\u7b2c 4 \u6b21\u8bf7\u6c42\u65f6\uff0c\u56e0\u4e3a\u8d85\u8fc7\u4e86\u9608\u503c\uff0c\u4f1a\u88ab\u67d0\u4e2a worker \u54cd\u5e94 400\uff0c\u540e\u9762\u518d\u7528\u6b64 IP \u53d1\u9001\u8bf7\u6c42\u5230 workers\uff0c\u90fd\u4f1a\u54cd\u5e94 400\uff0c\u56e0\u4e3a\u8bf7\u6c42\u6570\u5728 workers \u95f4\u662f\u540c\u6b65\u7684\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">curl --header <span class=\"s2\">&#34;X-Forwarded-For: 0.0.0.0&#34;<\/span> -i localhost:8000\n\nHTTP\/1.1 <span class=\"m\">400<\/span> Bad Request\nToo many requests!\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>node \u4e0d\u540c worker \u8fdb\u7a0b\u6253\u5370 warn \u65e5\u5fd7\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"o\">[<\/span>65097<span class=\"o\">]<\/span> IP: 0.0.0.0 exceeded the maximum request quantity!\n<span class=\"o\">[<\/span>65100<span class=\"o\">]<\/span> IP: 0.0.0.0 exceeded the maximum request quantity!\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u518d\u6a21\u62df\u5176\u5b83 IP \u8bf7\u6c42\uff0c\u6b63\u5e38\u54cd\u5e94\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">curl --header <span class=\"s2\">&#34;X-Forwarded-For: 0.0.0.1&#34;<\/span> -i localhost:8000\n\nHTTP\/1.1 <span class=\"m\">200<\/span> OK\nhello world\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6d4b\u8bd5\u7ed3\u679c\u8bf4\u660e\uff0c\u8fd9\u4e2a\u4f8b\u5b50\u80fd\u7b80\u5355\u5b9e\u73b0 cluster workers IPC \u540c\u6b65 IP \u8bf7\u6c42\u6570\u91cf\uff0c\u8fdb\u884c IP \u9650\u6d41\u3002<\/p>\n<h5 id=\"\u5e76\u53d1\u6d4b\u8bd5\">\u5e76\u53d1\u6d4b\u8bd5<\/h5>\n<p>\u4e0a\u9762\u662f\u7528\u987a\u5e8f\u7684 HTTP \u8bf7\u6c42\u6d4b\u8bd5\uff0c\u672c\u4f8b\u4e2d\u7684 Node \u670d\u52a1\u80fd\u987a\u5229\u5904\u7406\u4e32\u884c\u7684 IP \u8bf7\u6c42\u9650\u6d41\uff0c\u4e0b\u9762\u5c1d\u8bd5\u5728<strong>\u5e76\u53d1<\/strong>\u8bf7\u6c42\u6761\u4ef6\u4e0b\uff0c\u662f\u5426\u8fd8\u80fd\u6309\u7167\u9884\u671f\u5904\u7406\uff1f<\/p>\n<p>\u4f7f\u7528 Apache \u538b\u529b\u6d4b\u8bd5\u5de5\u5177 <code>ab<\/code> \u6765\u6d4b\u8bd5\u5e76\u53d1\u7684 HTTP \u8bf7\u6c42\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">ab -H <span class=\"s1\">&#39;x-forwarded-for: 0.0.0.2&#39;<\/span> -n <span class=\"m\">10<\/span> -c <span class=\"m\">5<\/span> localhost:8000\/\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u53d1\u9001 10 \u6b21\u8bf7\u6c42\uff0c\u5e76\u53d1\u6570\u4e3a 5\uff0c\u5728\u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u5e94\u8be5\u53ea\u6709\u524d 3 \u6b21\u8bf7\u6c42\u6210\u529f\uff0c\u540e\u9762 7 \u6b21\u90fd\u4f1a\u5931\u8d25\u3002\u5b9e\u9645\u7ed3\u679c\u5f80\u5f80\u5f88\u9aa8\u611f\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-fallback\" data-lang=\"fallback\">Concurrency Level:      5\nComplete requests:      10\nFailed requests:        4\nNon-2xx responses:      4\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><code>ab<\/code> \u7684\u6d4b\u8bd5\u7ed3\u679c\u4e2d\uff0c\u53ef\u4ee5\u770b\u5230\u5931\u8d25\u7684\u8bf7\u6c42\u6570\u662f 4\uff0c\u8bf4\u660e\u6709 6 \u6b21\u8bf7\u6c42\u6210\u529f\u4e86\uff0c\u8ddf\u9884\u671f\u4e0d\u7b26\u3002\u56e0\u4e3a\u5728\u5e76\u53d1\u60c5\u51b5\u4e0b\uff0c\u591a\u4e2a workers \u540c\u65f6\u5904\u7406 HTTP \u8bf7\u6c42\uff0c\u53ef\u80fd\u5728 workers \u540c\u6b65\u5e76\u63a5\u6536\u5230 IP \u8bf7\u6c42\u6d88\u606f\u524d\uff0c\u5f53\u524d\u7684 HTTP \u8bf7\u6c42\u5df2\u7ecf\u5904\u7406\u5b8c\u54cd\u5e94\u4e86\u3002\u8fd9\u662f IPC \u5f02\u6b65\u5bfc\u81f4\u7684\u95ee\u9898\uff0c\u800c\u5224\u65ad\u662f\u5426\u8d85\u8fc7\u9608\u503c\u7684\u903b\u8f91\u53c8\u662f\u540c\u6b65\u7684\uff0c\u6240\u4ee5\u4f1a\u6709\u6f0f\u7f51\u4e4b\u9c7c\u9003\u8fc7\u4e86\u9650\u6d41\u3002<\/p>\n<h5 id=\"\u5b58\u5728\u7684\u95ee\u9898\">\u5b58\u5728\u7684\u95ee\u9898<\/h5>\n<p>\u4e25\u683c\u6765\u8bf4\uff0cworkers \u95f4\u9700\u8981\u5b9e\u65f6\u540c\u6b65\u7684\u72b6\u6001\u4e0d\u5e94\u8be5\u7531 worker \u81ea\u5df1\u7ba1\u7406\uff0c\u800c\u662f\u4ea4\u7531\u7b2c\u4e09\u65b9\u6765\u7ba1\u7406\u5171\u4eab\u72b6\u6001\uff0cworker \u53ea\u8d1f\u8d23\u53d1\u9001\u66f4\u65b0\u6307\u4ee4\u548c\u83b7\u53d6\u72b6\u6001\uff0c\u8fd9\u4e2a\u7b2c\u4e09\u65b9\u53ef\u80fd\u662f master \u6216\u8005 Redis \u7b49\uff0c\u540c\u65f6\u5224\u65ad\u8d85\u8fc7\u9608\u503c\u7684\u903b\u8f91\u4e5f\u5e94\u8be5\u662f\u5f02\u6b65\u83b7\u53d6\u5b8c\u5f53\u524d\u72b6\u6001\u518d\u6267\u884c\u3002<\/p>\n<p>\u672c\u4f8b\u4e2d\u4e5f\u8fd8\u6709\u4e00\u4e9b\u95ee\u9898\u5b58\u5728\uff0c\u6bd4\u5982\uff1a<\/p>\n<ul>\n<li>\n<p>\u4e00\u4e2a worker \u88ab kill \u6389\uff0cmaster \u518d\u91cd\u65b0 fork \u51fa\u6765\u7684\u65b0 worker\uff0cIP \u8bb0\u5f55\u8bf7\u6c42\u6570\u662f\u4ece 0 \u5f00\u59cb\u8ba1\u6570\u7684\uff0c\u67d0\u4e2a\u88ab\u9650\u6d41\u7684 IP \u5982\u679c\u88ab\u8f6c\u53d1\u5230\u8fd9\u4e2a worker \u4e0a\u5904\u7406\uff0c\u4f1a\u4fa5\u5e78\u9003\u8fc7\u4e00\u52ab\uff1b<\/p>\n<\/li>\n<li>\n<p>\u6240\u6709\u7684 workers IPC \u90fd\u7531 master \u4ee3\u7406\uff0c\u4f1a\u52a0\u91cd master \u7684\u5904\u7406\u8d1f\u62c5\uff0c\u6d41\u91cf\u589e\u957f\u540e\u53ef\u80fd\u4f1a\u51fa\u73b0\u6027\u80fd\u95ee\u9898\uff1b<\/p>\n<\/li>\n<li>\n<p>\u67d0\u4e2a IP \u88ab\u9650\u6d41\u540e\uff0c\u540e\u9762\u7684\u6bcf\u6b21\u8bf7\u6c42\u90fd\u4f1a\u5728 workers \u95f4\u7ee7\u7eed\u540c\u6b65\u8ba1\u6570\uff0c\u6709\u70b9\u591a\u4f59\uff1b<\/p>\n<\/li>\n<li>\n<p>\u2026<\/p>\n<\/li>\n<\/ul>\n<h4 id=\"clusterhubhttpsgithubcomfentclusterhub-\u6a21\u5757\"><a href=\"https:\/\/github.com\/fent\/clusterhub\">clusterhub<\/a> \u6a21\u5757<\/h4>\n<p>\u4e0a\u9762\u7684 master \u4ee3\u7406 workers IPC \u4e5f\u6709\u5e93\u53ef\u4ee5\u652f\u6301\uff0c<a href=\"https:\/\/github.com\/fent\/clusterhub\">clusterhub<\/a> \u8fd9\u4e2a Node \u6a21\u5757\u63d0\u4f9b\u4e86 <strong>EventEmitter<\/strong> \u7684\u65b9\u5f0f\u6765\u8ba9 master \u4ee3\u7406 workers IPC\uff0c\u5b9e\u9645\u9879\u76ee\u4e2d\u53ef\u4ee5\u5f15\u5165\u8fd9\u4e2a\u6a21\u5757\u3002<\/p>\n<p>\u73b0\u5728\u5c31\u6765\u8bd5\u4e00\u4e0b\u7528 <strong>clusterhub<\/strong> \u6a21\u5757\u6539\u5199\u4e0a\u9762\u7684\u4f8b\u5b50\uff1a<\/p>\n<h5 id=\"masterjs-1\">master.js<\/h5>\n<p>master \u4e2d\u5c31\u53ef\u4ee5\u79fb\u9664\u4e0a\u9762\u8f6c\u53d1\u6d88\u606f\u7684\u903b\u8f91\uff0c\u4f46\u662f\u4e00\u5b9a\u8981\u5f15\u5165 <strong>clusterhub<\/strong> \u6a21\u5757\uff0c\u5373\u4f7f master \u4e2d\u4e0d\u8c03\u7528 <strong>clusterhub<\/strong> API\uff0c\u56e0\u4e3a <strong>clusterhub<\/strong> \u5185\u90e8\u8981\u5728 master \u8fdb\u7a0b\u4e2d\u6ce8\u518c\u4ee3\u7406\u7684\u903b\u8f91\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">cluster<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;cluster&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">numCPUs<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;os&#39;<\/span><span class=\"p\">).<\/span><span class=\"nx\">cpus<\/span><span class=\"p\">().<\/span><span class=\"nx\">length<\/span>\n<span class=\"c1\">\/\/ \u6ce8\u610f\u5f15\u5165 clusterhub\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;clusterhub&#39;<\/span><span class=\"p\">)<\/span>\n\n<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">isMaster<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Master <\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> is running`<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"c1\">\/\/ Fork workers.\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kd\">let<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">numCPUs<\/span><span class=\"p\">;<\/span> <span class=\"nx\">i<\/span><span class=\"o\">++<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">fork<\/span><span class=\"p\">()<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;exit&#39;<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">worker<\/span><span class=\"p\">,<\/span> <span class=\"nx\">code<\/span><span class=\"p\">,<\/span> <span class=\"nx\">signal<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`worker <\/span><span class=\"si\">${<\/span><span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> died`<\/span><span class=\"p\">)<\/span>\n    <span class=\"c1\">\/\/ accidental exit, add new worker\n<\/span><span class=\"c1\"><\/span>    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">worker<\/span><span class=\"p\">.<\/span><span class=\"nx\">exitedAfterDisconnect<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">cluster<\/span><span class=\"p\">.<\/span><span class=\"nx\">fork<\/span><span class=\"p\">()<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;.\/worker&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h5 id=\"workerjs-1\">worker.js<\/h5>\n<p>worker \u4e2d\u5c31\u4e0d\u9700\u8981\u76d1\u542c <code>process message<\/code> \u4e8b\u4ef6\u4e86\uff0c\u76f4\u63a5\u5728 <strong>hub<\/strong> \u4e0a\u76d1\u542c <code>SYNC_REQUEST<\/code> \u4e8b\u4ef6\uff0c\u4e0e\u5176\u5b83 workers \u540c\u6b65 IP \u65f6\u8c03\u7528 <code>hub.emitRemote()<\/code>\uff0c<strong>clusterhub<\/strong> \u4f1a\u5728\u5185\u90e8\u5c01\u88c5\u4fe1\u606f\u53d1\u9001\u7ed9 master\uff0cmaster \u518d\u8f6c\u53d1\u7ed9\u5176\u5b83 workers\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">http<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;http&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">hub<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;clusterhub&#39;<\/span><span class=\"p\">)<\/span>\n\n<span class=\"kr\">const<\/span> <span class=\"nx\">ipRecord<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">MAX_REQUEST<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">3<\/span>\n\n<span class=\"c1\">\/\/ Workers can share any TCP connection\n<\/span><span class=\"c1\">\/\/ In this case it is an HTTP server\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">http<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">createServer<\/span><span class=\"p\">((<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">realIP<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;x-forwarded-for&#39;<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">connection<\/span><span class=\"p\">.<\/span><span class=\"nx\">remoteAddress<\/span>\n\n    <span class=\"nx\">realIP<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">syncRequest<\/span><span class=\"p\">(<\/span><span class=\"nx\">realIP<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">realIP<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">realIP<\/span><span class=\"p\">]<\/span> <span class=\"o\">&gt;<\/span> <span class=\"nx\">MAX_REQUEST<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">warn<\/span><span class=\"p\">(<\/span><span class=\"sb\">`[<\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\">] IP: <\/span><span class=\"si\">${<\/span><span class=\"nx\">realIP<\/span><span class=\"si\">}<\/span><span class=\"sb\"> exceeded the maximum request quantity!`<\/span><span class=\"p\">)<\/span>\n      <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeHead<\/span><span class=\"p\">(<\/span><span class=\"mi\">400<\/span><span class=\"p\">).<\/span><span class=\"nx\">end<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Too many requests!&#39;<\/span><span class=\"p\">)<\/span>\n      <span class=\"k\">return<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeHead<\/span><span class=\"p\">(<\/span><span class=\"mi\">200<\/span><span class=\"p\">).<\/span><span class=\"nx\">end<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;hello world\\n&#39;<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">})<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">listen<\/span><span class=\"p\">(<\/span><span class=\"mi\">8000<\/span><span class=\"p\">)<\/span>\n\n<span class=\"c1\">\/\/ listen SYNC_REQUEST on hub\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">hub<\/span><span class=\"p\">.<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;SYNC_REQUEST&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ip<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n<span class=\"p\">})<\/span>\n\n<span class=\"c1\">\/\/ increase ip request number and notify other workers by hub.emitRemote()\n<\/span><span class=\"c1\"><\/span><span class=\"kd\">function<\/span> <span class=\"nx\">syncRequest<\/span><span class=\"p\">(<\/span><span class=\"nx\">ip<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">ipRecord<\/span><span class=\"p\">[<\/span><span class=\"nx\">ip<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span>\n  <span class=\"nx\">hub<\/span><span class=\"p\">.<\/span><span class=\"nx\">emitRemote<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;SYNC_REQUEST&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ip<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Worker <\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> started`<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6d4b\u8bd5\u7ed3\u679c\u540c\u4e0a\u3002<strong>clusterhub<\/strong> \u7701\u53bb\u4e86\u6211\u4eec\u624b\u52a8\u5b9e\u73b0 master \u4ee3\u7406\u903b\u8f91\u7684\u6d41\u7a0b\uff0c\u8fd8\u63d0\u4f9b\u5728\u5f53\u524d\u8fdb\u7a0b\u89e6\u53d1\u4e8b\u4ef6\u7684 API <a href=\"https:\/\/github.com\/fent\/clusterhub#hubemitlocalevent-args\">clusterhub.emitLocal()<\/a> \u3002\u53e6\u5916 <strong>clusterhub<\/strong> \u5f15\u5165\u4e86 <a href=\"https:\/\/github.com\/hij1nx\/EventVat\">EventVat<\/a> \u4f5c\u4e3a\u8de8\u8fdb\u7a0b\u7684 key-value \u6570\u636e\u5e93\uff0c\u8fd9\u4e0d\u5c31\u662f\u524d\u9762\u63d0\u5230\u7684\u7b2c\u4e09\u65b9\u72b6\u6001\u7ba1\u7406\u5417\uff1f<\/p>\n<p>\u4e8b\u60c5\u53d8\u5f97\u66f4\u7b80\u5355\u4e86\uff0c\u76f4\u63a5\u628a IP \u8bf7\u6c42\u8bb0\u5f55\u5b58\u5230 master - workers \u5171\u4eab\u7684 key-value DB \u91cc\uff0c\u6bcf\u6b21\u5904\u7406 IP \u8bf7\u6c42\u65f6\uff0c\u9996\u5148\u4ece DB \u5f02\u6b65\u83b7\u53d6\u5230\u5f53\u524d IP \u7d2f\u8ba1\u8bf7\u6c42\u6570\uff0c\u7136\u540e\u518d\u51b3\u5b9a\u662f\u5426\u9650\u6d41\uff1b\u867d\u7136\u589e\u52a0\u4e86 HTTP \u5904\u7406\u5ef6\u8fdf\uff0c\u4f46\u5728\u903b\u8f91\u4e0a\u63d0\u9ad8\u4e86\u51c6\u786e\u7387\u548c\u5408\u7406\u6027\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">http<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;http&#39;<\/span><span class=\"p\">)<\/span>\n<span class=\"kr\">const<\/span> <span class=\"nx\">hub<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;clusterhub&#39;<\/span><span class=\"p\">)<\/span>\n\n<span class=\"kr\">const<\/span> <span class=\"nx\">MAX_REQUEST<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">100<\/span>\n\n<span class=\"c1\">\/\/ Workers can share any TCP connection\n<\/span><span class=\"c1\">\/\/ In this case it is an HTTP server\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">http<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">createServer<\/span><span class=\"p\">((<\/span><span class=\"nx\">req<\/span><span class=\"p\">,<\/span> <span class=\"nx\">res<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">realIP<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">headers<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;x-forwarded-for&#39;<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">req<\/span><span class=\"p\">.<\/span><span class=\"nx\">connection<\/span><span class=\"p\">.<\/span><span class=\"nx\">remoteAddress<\/span>\n\n    <span class=\"c1\">\/\/ increment the IP integer value in key-value db\n<\/span><span class=\"c1\"><\/span>    <span class=\"nx\">realIP<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">hub<\/span><span class=\"p\">.<\/span><span class=\"nx\">incr<\/span><span class=\"p\">(<\/span><span class=\"nx\">realIP<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"c1\">\/\/ first get the IP integer value asynchronously, then decide whether to limit\n<\/span><span class=\"c1\"><\/span>    <span class=\"nx\">hub<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">realIP<\/span><span class=\"p\">,<\/span> <span class=\"nx\">count<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">count<\/span> <span class=\"o\">&gt;<\/span> <span class=\"nx\">MAX_REQUEST<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">warn<\/span><span class=\"p\">(<\/span><span class=\"sb\">`[<\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\">] IP: <\/span><span class=\"si\">${<\/span><span class=\"nx\">realIP<\/span><span class=\"si\">}<\/span><span class=\"sb\"> exceeded the maximum request quantity!`<\/span><span class=\"p\">)<\/span>\n        <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeHead<\/span><span class=\"p\">(<\/span><span class=\"mi\">400<\/span><span class=\"p\">).<\/span><span class=\"nx\">end<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Too many requests!&#39;<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span>\n      <span class=\"p\">}<\/span>\n      <span class=\"nx\">res<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeHead<\/span><span class=\"p\">(<\/span><span class=\"mi\">200<\/span><span class=\"p\">).<\/span><span class=\"nx\">end<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;hello world\\n&#39;<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">})<\/span>\n  <span class=\"p\">})<\/span>\n  <span class=\"p\">.<\/span><span class=\"nx\">listen<\/span><span class=\"p\">(<\/span><span class=\"mi\">8000<\/span><span class=\"p\">)<\/span>\n\n<span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"sb\">`Worker <\/span><span class=\"si\">${<\/span><span class=\"nx\">process<\/span><span class=\"p\">.<\/span><span class=\"nx\">pid<\/span><span class=\"si\">}<\/span><span class=\"sb\"> started`<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h5 id=\"\u6d4b\u8bd5-1\">\u6d4b\u8bd5<\/h5>\n<p><code>ab<\/code> \u547d\u4ee4\u8bbe\u7f6e\u5728 1000 \u8bf7\u6c42\u6570\uff0c\u5e76\u53d1 100 \u7684\u6761\u4ef6\u4e0b\uff0c\u5bf9\u9608\u503c\u4e3a 100 \u7684\u4f8b\u5b50\u8fdb\u884c\u6d4b\u8bd5\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">ab -H <span class=\"s1\">&#39;x-forwarded-for: 0.0.0.5&#39;<\/span> -n <span class=\"m\">1000<\/span> -c <span class=\"m\">100<\/span> localhost:8000\/\n\nConcurrency Level:      <span class=\"m\">100<\/span>\nTime taken <span class=\"k\">for<\/span> tests:   0.244 seconds\nComplete requests:      <span class=\"m\">1000<\/span>\nFailed requests:        <span class=\"m\">900<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6d4b\u8bd5\u7ed3\u679c\u8868\u793a\u53ea\u6709 100 \u4e2a\u8bf7\u6c42\u6210\u529f\u4e86\uff0c\u8bf4\u660e\u7b26\u5408\u9884\u671f\u3002<\/p>\n<h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2>\n<p>\u672c\u6587\u9996\u5148\u4ecb\u7ecd\u4e86 Node Cluster \u76f8\u6bd4 Node \u5355\u8fdb\u7a0b\u7684\u4f18\u52bf\uff0c\u5e76\u5c55\u793a\u4e86 Cluster \u7684\u7b80\u5355\u5b9e\u8df5\uff0c\u7136\u540e\u5f15\u51fa cluster workers IPC \u7684\u95ee\u9898\uff0c\u7ed9\u51fa\u4e24\u79cd\u5b9e\u73b0\u65b9\u5f0f\uff1a<\/p>\n<ul>\n<li>Unix Domain Socket IPC<\/li>\n<li>Master \u4ee3\u7406<\/li>\n<\/ul>\n<p>\u57fa\u4e8e Master \u4ee3\u7406\u65b9\u5f0f\u5b9e\u8df5\u4e86\u4e00\u4e2a IP \u9650\u6d41\u7684\u4f8b\u5b50\uff0c\u6307\u51fa\u5b58\u5728\u7684\u95ee\u9898\uff08\u5e76\u53d1\u3001\u5f02\u6b65\u3001\u5171\u4eab\u72b6\u6001\u7ba1\u7406\uff09\uff0c\u6700\u540e\u5f15\u5165 <strong>clusterhub<\/strong> \u6a21\u5757\u505a\u4f18\u5316\uff0c\u521d\u6b65\u89e3\u51b3\u4e86\u63d0\u5230\u7684\u95ee\u9898\u3002<\/p>\n<p>libuv \u521b\u5efa\u7684 master - worker IPC \u4e3a workers IPC \u63d0\u4f9b\u4e86\u4e00\u6761\u6377\u5f84\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190627003616.png\" alt=\"\"><\/p>"},{"title":"Vue MVVM \u5b9e\u73b0\uff08Proxy \u7bc7\uff09","link":"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm-proxy\/","pubDate":"Sat, 20 Apr 2019 10:32:43 +0800","guid":"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm-proxy\/","description":"<p><a href=\"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm\/\">\u4e0a\u4e00\u7bc7<\/a>\u5b9e\u73b0 MVVM <strong>\u6570\u636e\u52ab\u6301<\/strong>\u662f\u57fa\u4e8e ES5 \u7684 <code>Object.defineProperty()<\/code> API\uff0c\u65b0\u7684\u8f6e\u5b50\u5c06\u4f7f\u7528 <code>Proxy<\/code> \u66ff\u4ee3\uff0cfollow Vue 3\uff1b\u5728\u539f\u6709\u8f6e\u5b50\u7684\u57fa\u7840\u4e0a\u505a\u4e9b\u6539\u9020\uff0c\u9002\u914d <code>Proxy<\/code>\u3002<\/p>\n<p><code>Object.defineProperty()<\/code> \u548c <code>Proxy<\/code> \u5b9e\u73b0 MVVM \u6570\u636e\u52ab\u6301\u7684\u533a\u522b\u662f\uff1a<code>Object.defineProperty()<\/code> \u9700\u8981\u4e3a\u6bcf\u4e2a key \u5b9a\u4e49 getter \u548c setter\uff0c\u4e5f\u5c31\u662f\u9700\u8981\u904d\u5386 <code>data<\/code> \u4e0b\u7684\u5168\u90e8\u5b50\u5c5e\u6027\uff1b\u800c <code>Proxy<\/code> \u53ea\u9700\u8981\u4e3a <code>data<\/code> \u672c\u8eab\u548c\u5185\u90e8\u5d4c\u5957\u7684\u5bf9\u8c61\u521b\u5efa\u4ee3\u7406\uff0c\u6bcf\u4e2a\u5bf9\u8c61\u7edf\u4e00\u4ee3\u7406\u8bbf\u95ee\u5185\u90e8\u5c5e\u6027\uff0c\u5bf9\u5916\u63d0\u4f9b\u4ee3\u7406\u7684\u5f15\u7528\u3002<\/p>\n<h2 id=\"mvvm-proxy-\u539f\u7406\u5b9e\u73b0\">MVVM Proxy \u539f\u7406\u5b9e\u73b0<\/h2>\n<p>\u6548\u679c\uff08\u540c\u4e0a\u4e00\u4e2a\u8f6e\u5b50\uff09\uff1a<\/p>\n<!-- raw HTML omitted -->\n<p><strong>index.html<\/strong> \u548c <strong>Compiler<\/strong> \u6a21\u5757\u4e0d\u9700\u8981\u6539\u52a8\uff0c\u8be6\u60c5\u89c1 <a href=\"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm\/\">\u4e0a\u4e00\u7bc7<\/a><\/p>\n<h3 id=\"mvvm-\u6a21\u5757\">MVVM \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p><strong>MVVM<\/strong> \u521d\u59cb\u5316\u65f6\u9700\u8981\u4ee3\u7406 <code>this.xxx<\/code> \u5230 <code>this.$data.xxx<\/code> \u6216\u8005 <code>options.computed.xxx<\/code>\uff0c\u6240\u4ee5\u7ed9 <code>this<\/code> \u521b\u5efa\u4e00\u4e2a <code>Proxy<\/code> \u4ee3\u7406\uff0c\u5224\u65ad <code>key<\/code> \u5728 <code>this<\/code> \u672c\u8eab\u3001<code>data<\/code>\u3001<code>methods<\/code>\u3001<code>computed<\/code> \u4e2d\uff0c\u5206\u522b\u901a\u8fc7 <code>Reflect.get()<\/code> \u5728\u5bf9\u5e94\u7684 object \u4e0a\u83b7\u53d6 key \u503c\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">_proxyThis<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">$options<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">computed<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">$options<\/span>\n    <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Proxy<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ \u8bbf\u95ee MVVM \u5b9e\u4f8b\u5c5e\u6027\n<\/span><span class=\"c1\"><\/span>        <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">key<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">target<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n        <span class=\"c1\">\/\/ \u8bbf\u95ee data \u5c5e\u6027\n<\/span><span class=\"c1\"><\/span>        <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">key<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">$options<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span>\n          <span class=\"k\">return<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">$data<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n        <span class=\"c1\">\/\/ \u8bbf\u95ee method\n<\/span><span class=\"c1\"><\/span>        <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">key<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">$options<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">)<\/span>\n          <span class=\"k\">return<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">$options<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n        <span class=\"c1\">\/\/ \u8bbf\u95ee computed \u5c5e\u6027\n<\/span><span class=\"c1\"><\/span>        <span class=\"k\">return<\/span> <span class=\"k\">typeof<\/span> <span class=\"nx\">computed<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;function&#39;<\/span>\n          <span class=\"o\">?<\/span> <span class=\"nx\">computed<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">].<\/span><span class=\"nx\">call<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">_vm<\/span><span class=\"p\">)<\/span>\n          <span class=\"o\">:<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">computed<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n      <span class=\"p\">},<\/span>\n      <span class=\"nx\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ \u8bbe\u7f6e data \u5c5e\u6027\n<\/span><span class=\"c1\"><\/span>        <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">target<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">])<\/span> <span class=\"p\">{<\/span>\n          <span class=\"k\">return<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">$data<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n      <span class=\"p\">},<\/span>\n    <span class=\"p\">})<\/span>\n  <span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><code>new Proxy(this, handler)<\/code> \u521b\u5efa\u7684 <code>this<\/code> \u4ee3\u7406\u9700\u8981\u4f5c\u4e3a <code>MVVM<\/code> \u6784\u9020\u51fd\u6570\u7684\u5b9e\u4f8b\u5bf9\u8c61\u8fd4\u56de\uff0c\u56e0\u4e3a\u63d0\u4f9b\u7ed9\u5916\u90e8\u8bbf\u95ee\u7684\u662f\u4ee3\u7406\uff0c\u5373 <code>this._vm<\/code>\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">constructor<\/span><span class=\"p\">(<\/span><span class=\"nx\">options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{})<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ ...\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_vm<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_proxyThis<\/span><span class=\"p\">()<\/span>\n\t<span class=\"c1\">\/\/ ...\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">return<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_vm<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u7136\u540e\u5c06 <code>methods<\/code> \u51fd\u6570\u4e2d\u7684 <code>this<\/code> \u7ed1\u5b9a\u5230 <code>this._vm<\/code> \u4e0a:<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">_bindMethods<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">methods<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$options<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span>\n  <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nx\">keys<\/span><span class=\"p\">(<\/span><span class=\"nx\">methods<\/span><span class=\"p\">).<\/span><span class=\"nx\">forEach<\/span><span class=\"p\">(<\/span><span class=\"nx\">method<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">methods<\/span><span class=\"p\">[<\/span><span class=\"nx\">method<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">methods<\/span><span class=\"p\">[<\/span><span class=\"nx\">method<\/span><span class=\"p\">].<\/span><span class=\"nx\">bind<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_vm<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u8c03\u7528 <code>Observer<\/code> \u7ed9 <code>options.data<\/code> \u548c\u5d4c\u5957\u5bf9\u8c61\u521b\u5efa\u4ee3\u7406\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$data<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">observe<\/span><span class=\"p\">(<\/span><span class=\"nx\">options<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6700\u540e\u8fd8\u662f\u4e00\u6837\u8c03\u7528 <code>Compiler<\/code> \u89e3\u6790\u6a21\u677f\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$compile<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nx\">Compiler<\/span><span class=\"p\">(<\/span><span class=\"nx\">options<\/span><span class=\"p\">.<\/span><span class=\"nx\">el<\/span> <span class=\"o\">||<\/span> <span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nx\">body<\/span><span class=\"p\">,<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_vm<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"dep-\u6a21\u5757\">Dep \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p><strong>Dep<\/strong> \u6a21\u5757\u5b58\u50a8\u7ed3\u6784\u8ddf\u4e0a\u4e2a\u8f6e\u5b50\u7684 Dep \u4e0d\u540c\uff0c\u56e0\u4e3a\u4f7f\u7528 <code>Proxy<\/code> \u4ee3\u7406\u540e\uff0c\u53ea\u80fd\u4e3a\u6bcf\u4e2a\u5bf9\u8c61\u7ed1\u5b9a\u4e00\u4e2a <code>Dep<\/code> \u5b9e\u4f8b\uff0c\u4e00\u4e2a <code>Dep<\/code> \u5b9e\u4f8b\u5305\u542b\u8be5\u5bf9\u8c61\u5185\u90e8<strong>\u6240\u6709\u5c5e\u6027<\/strong>\u7684\u8ba2\u9605\u8005\uff0c\u800c\u4e0d\u662f\u4e4b\u524d\u7684\u4e00\u4e2a\u5c5e\u6027\u4e00\u4e2a <code>Dep<\/code> \u5b9e\u4f8b\u3002<\/p>\n<p>\u4e3a\u4e86\u4fdd\u8bc1\u5b58\u50a8\u8ba2\u9605\u8005\u7684\u6570\u636e\u7ed3\u6784\u7684\u552f\u4e00\u6027\uff0c\u4f7f\u7528 <strong>Set<\/strong> \u7ed3\u6784\u4fdd\u8bc1\u8ba2\u9605\u8005\u4e0d\u4f1a\u91cd\u590d\uff1b\u5916\u5c42\u4f7f\u7528 <strong>Map<\/strong> \u7ed3\u6784\u5b58\u50a8 <strong>key - Set<\/strong> \u7684\u6620\u5c04\u5173\u7cfb\u3002<\/p>\n<p>\u8ba2\u9605\u4e2d\u5fc3\u63d0\u4f9b\u7684\u6bcf\u4e2a\u63a5\u53e3\uff0c\u90fd\u9700\u8981 <code>key<\/code> \u548c <code>sub<\/code> \u53c2\u6570\uff0c\u6839\u636e <code>key<\/code> \u627e\u51fa <strong>Map<\/strong> \u4e2d\u6620\u5c04\u7684 <strong>Set<\/strong>\uff0c\u5728\u8ba2\u9605\u8005 <strong>Set<\/strong> \u4e2d\u8fdb\u884c\u64cd\u4f5c\u3002<\/p>\n<h3 id=\"observer-\u6a21\u5757\">Observer \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p><strong>Observer<\/strong> \u6a21\u5757\u4f7f\u7528 <code>Proxy<\/code> \u4ee3\u7406 <code>data<\/code> \u4e2d\u5d4c\u5957\u5bf9\u8c61\u7684\u8bbf\u95ee\u3002<\/p>\n<p>\u5bfc\u51fa\u7684 <code>observe<\/code> \u51fd\u6570\u9012\u5f52\u904d\u5386 <code>data<\/code> \u5185\u90e8\u5c5e\u6027\uff0c\u9047\u5230\u5bf9\u8c61\u5c31\u521b\u5efa\u4e00\u4e2a <code>Proxy<\/code> \u8986\u76d6\u539f\u59cb\u5bf9\u8c61\u503c\uff0c\u6700\u540e\u8fd4\u56de <code>data<\/code> \u5bf9\u8c61\u7684\u4ee3\u7406\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">export<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">observe<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ data \u4e0d\u662f\u5bf9\u8c61\u65e0\u6cd5\u52ab\u6301\uff0c\u5ffd\u7565\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">data<\/span> <span class=\"o\">||<\/span> <span class=\"k\">typeof<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">!==<\/span> <span class=\"s1\">&#39;object&#39;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nx\">data<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"c1\">\/\/ \u6df1\u5ea6\u76d1\u542c\n<\/span><span class=\"c1\"><\/span>  <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nx\">keys<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">).<\/span><span class=\"nx\">forEach<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">data<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">observe<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">])<\/span>\n  <span class=\"p\">})<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"nx\">Observer<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><code>proxyObject<\/code> \u51fd\u6570\u4e3a <code>data<\/code> \u4e2d\u7684\u6bcf\u4e2a\u5d4c\u5957\u5bf9\u8c61\u521b\u5efa\u4ee3\u7406\u548c\u7ed1\u5b9a\u7684 <code>Dep<\/code> \u5b9e\u4f8b\u3002\u8ddf\u4e0a\u4e2a\u8f6e\u5b50\u4e0d\u540c\uff0c\u5728 getter \u4e2d\uff0c\u8fd9\u91cc\u7b80\u5316\u4e86\u6dfb\u52a0\u8ba2\u9605\u8005\u7684\u903b\u8f91\uff0c\u5982\u679c\u5224\u65ad <code>Dep.target<\/code> \u5b58\u5728\uff0c\u76f4\u63a5\u901a\u8fc7\u95ed\u5305\u5728\u7ed1\u5b9a\u7684 <code>Dep<\/code> \u5b9e\u4f8b\u4e0a\u628a\u8ba2\u9605\u8be5 <code>key<\/code> \u7684 <code>Watcher<\/code> \u5b9e\u4f8b\u6dfb\u52a0\u5230\u8ba2\u9605\u8005\u4e2d\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">proxyObject<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">obj<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">dep<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nx\">Dep<\/span><span class=\"p\">()<\/span>\n  <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Proxy<\/span><span class=\"p\">(<\/span><span class=\"nx\">obj<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">get<\/span><span class=\"o\">:<\/span> <span class=\"kd\">function<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"c1\">\/\/ \u5982\u679c\u8ba2\u9605\u8005\u5b58\u5728\uff0c\u76f4\u63a5\u6dfb\u52a0\u8ba2\u9605\n<\/span><span class=\"c1\"><\/span>      <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">Dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">addSub<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">Dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">)<\/span>\n      <span class=\"p\">}<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">},<\/span>\n    <span class=\"nx\">set<\/span><span class=\"o\">:<\/span> <span class=\"kd\">function<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">get<\/span><span class=\"p\">(<\/span><span class=\"nx\">receiver<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">)<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">value<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span>\n      <span class=\"p\">}<\/span>\n      <span class=\"kr\">const<\/span> <span class=\"nx\">res<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">Reflect<\/span><span class=\"p\">.<\/span><span class=\"nx\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">target<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">observe<\/span><span class=\"p\">(<\/span><span class=\"nx\">value<\/span><span class=\"p\">),<\/span> <span class=\"nx\">receiver<\/span><span class=\"p\">)<\/span>\n      <span class=\"nx\">dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">notify<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">)<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">res<\/span>\n    <span class=\"p\">},<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"watcher-\u6a21\u5757\">Watcher \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p>\u56e0\u4e3a\u6dfb\u52a0\u8ba2\u9605\u8005\u7684\u903b\u8f91\u5df2\u7ecf\u5728 <code>Observer<\/code> \u6a21\u5757\u505a\u4e86\uff0c\u6240\u4ee5 <code>Watcher<\/code> \u6a21\u5757\u5220\u9664\u4e86 <code>applyDep()<\/code> \u65b9\u6cd5\uff0c\u5176\u5b83\u4e0d\u53d8\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ applyDep(dep) {\n<\/span><span class=\"c1\">\/\/   if (!this.depIds.hasOwnProperty(dep.id)) {\n<\/span><span class=\"c1\">\/\/     dep.addSub(this)\n<\/span><span class=\"c1\">\/\/     this.depIds[dep.id] = dep\n<\/span><span class=\"c1\">\/\/   }\n<\/span><span class=\"c1\">\/\/ }\n<\/span><\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"\u65b0\u7684\u6a21\u5757\u5173\u7cfb\u56fe\">\u65b0\u7684\u6a21\u5757\u5173\u7cfb\u56fe<\/h3>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190426164617.png\" alt=\"\"><\/p>\n<h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2>\n<p>Vue 3.0 \u4f7f\u7528\u4e86 <strong>Proxy<\/strong> \u540e\uff0c\u5c06\u4f1a\u6d88\u9664\u4e4b\u524d  Vue 2.x \u4e2d\u57fa\u4e8e <code>Object.defineProperty<\/code> \u7684\u5b9e\u73b0\u6240\u5b58\u5728\u7684\u4e00\u4e9b\u9650\u5236\uff1a\u65e0\u6cd5\u76d1\u542c <strong>\u5c5e\u6027\u7684\u6dfb\u52a0\u548c\u5220\u9664<\/strong>\u3001<strong>\u6570\u7ec4\u7d22\u5f15\u503c\u548c\u957f\u5ea6\u7684\u53d8\u66f4<\/strong>\u3002<\/p>\n<p>GitHub \u5730\u5740\uff1a<a href=\"https:\/\/github.com\/Jancat\/vue-mvvm-proxy\">https:\/\/github.com\/Jancat\/vue-mvvm-proxy<\/a><\/p>\n<h2 id=\"\u53c2\u8003\">\u53c2\u8003<\/h2>\n<p><a href=\"https:\/\/github.com\/xiaomuzhu\/proxy-vue\">https:\/\/github.com\/xiaomuzhu\/proxy-vue<\/a><\/p>\n"},{"title":"Vue MVVM \u5b9e\u73b0\uff08defineProperty \u7bc7\uff09","link":"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm\/","pubDate":"Fri, 19 Apr 2019 23:33:14 +0800","guid":"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm\/","description":"<p><img src=\"https:\/\/cn.vuejs.org\/images\/data.png\" alt=\"Vue MVVM Poster\"><\/p>\n<h2 id=\"vue-\u54cd\u5e94\u5f0f\u539f\u7406\">Vue \u54cd\u5e94\u5f0f\u539f\u7406<\/h2>\n<p>Vue 2.x \u7684\u54cd\u5e94\u5f0f\u539f\u7406\u662f\u901a\u8fc7 <strong>\u6570\u636e\u52ab\u6301<\/strong> \u548c <strong>\u53d1\u5e03-\u8ba2\u9605<\/strong>\u6a21\u5f0f\u5b9e\u73b0\u7684\u3002<\/p>\n<p>\u521d\u59cb\u5316 Vue \u5b9e\u4f8b\u65f6\u5185\u90e8\u5c31\u4f1a\u5b9a\u4e49\u6570\u636e\u52ab\u6301\u548c\u521b\u5efa\u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f\u3002<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/20190427110242.png\" alt=\"Vue MVVM\"><\/p>\n<h3 id=\"\u6570\u636e\u52ab\u6301\">\u6570\u636e\u52ab\u6301<\/h3>\n<p><strong>\u6570\u636e\u52ab\u6301<\/strong> \u901a\u8fc7 <code>Object.defineProperty()<\/code> \u52ab\u6301\u4f20\u5165\u7684 <code>data<\/code>\uff0c\u5bf9 <code>data<\/code> \u5c5e\u6027(\u5305\u62ec\u5d4c\u5957\u5bf9\u8c61) \u7684\u64cd\u4f5c\u8fdb\u884c\u76d1\u542c\uff08\u901a\u8fc7 getter\/setter\uff09\uff0c\u4ece\u800c\u89e6\u53d1\u4e00\u7cfb\u5217\u54cd\u5e94\u3002<\/p>\n<p>\u5728 <a href=\"https:\/\/cn.vuejs.org\/v2\/guide\/reactivity.html\">\u5b98\u65b9\u6587\u6863-\u6df1\u5165\u54cd\u5e94\u5f0f\u539f\u7406<\/a> \u4e2d\u4e5f\u8bf4\u660e\u4e86 Vue \u5728\u521d\u59cb\u5316\u5b9e\u4f8b\u540e <strong>\u65e0\u6cd5\u68c0\u6d4b\u5230\u5bf9\u8c61\u5c5e\u6027\u7684\u6dfb\u52a0\u6216\u5220\u9664<\/strong>\uff0c\u9700\u8981\u901a\u8fc7 <code>Vue.set(vm.someObject, 'b', 2)<\/code> \u6216\u8005 <code>this.$set(this.someObject,'b',2)<\/code> \u7684\u65b9\u5f0f\u52a8\u6001\u6dfb\u52a0\u65b0\u7684\u54cd\u5e94\u5f0f\u5c5e\u6027\uff0c\u5373\u7ed9\u65b0\u7684\u5c5e\u6027\u6dfb\u52a0 getter\/setter\u3002<\/p>\n<h3 id=\"\u53d1\u5e03-\u8ba2\u9605\">\u53d1\u5e03-\u8ba2\u9605<\/h3>\n<p><strong>\u53d1\u5e03-\u8ba2\u9605<\/strong>\u6a21\u5f0f\u662f\u6570\u636e\u52ab\u6301\u4e4b\u540e\u7684\u54cd\u5e94\uff0c\u8ba2\u9605\u4e2d\u5fc3 <strong>Dep<\/strong> \u6536\u96c6\u5bf9 <strong>Data<\/strong> \u5404\u4e2a\u5c5e\u6027\u7684\u4f9d\u8d56\uff0c<strong>Watcher<\/strong> \u4f5c\u4e3a\u8ba2\u9605\u8005\u8ba2\u9605\u8fd9\u4e9b\u4f9d\u8d56\uff1b\u4f9d\u8d56\u9879\u7684 setter \u89e6\u53d1\u65f6\uff0c\u4f1a\u901a\u77e5\u5bf9\u5e94\u7684 <strong>Watcher<\/strong>\uff0c\u4ece\u800c\u89e6\u53d1\u66f4\u65b0\u3002<\/p>\n<h3 id=\"mvvm-\u5404\u6a21\u5757\u804c\u8d23\">MVVM \u5404\u6a21\u5757\u804c\u8d23<\/h3>\n<ul>\n<li><strong>MVVM<\/strong>: Vue \u5b9e\u4f8b\u521d\u59cb\u5316\uff0c\u8c03\u7528 <strong>Observer<\/strong> \u6570\u636e\u52ab\u6301\uff0c\u8c03\u7528 <strong>Compiler<\/strong> \u89e3\u6790\u6a21\u677f\uff1b<\/li>\n<li><strong>Observer<\/strong>: \u52ab\u6301 data \u5168\u90e8\u5c5e\u6027\uff0c\u5b9a\u4e49 setter \u3001getter\uff0c\u6dfb\u52a0\u548c\u901a\u77e5\u8ba2\u9605\u8005\uff1b<\/li>\n<li><strong>Compiler<\/strong>: \u89e3\u6790\u6a21\u677f\u521d\u59cb\u5316\u89c6\u56fe\uff0c\u6536\u96c6\u6a21\u677f\u4e2d\u7684\u6570\u636e\u4f9d\u8d56\uff0c\u521b\u5efa\u8ba2\u9605\u8005\u8ba2\u9605\u53d8\u5316\uff0c\u7ed1\u5b9a\u66f4\u65b0\u51fd\u6570\uff1b<\/li>\n<li><strong>Dep<\/strong>\uff1a\u8ba2\u9605\u4e2d\u5fc3\uff0c\u63d0\u4f9b\u6dfb\u52a0\u3001\u79fb\u9664\u3001\u901a\u77e5\u8ba2\u9605\u7684\u63a5\u53e3\uff1b<\/li>\n<li><strong>Watcher<\/strong>: data \u5c5e\u6027\u7684\u8ba2\u9605\u8005\uff0c\u6536\u5230\u53d8\u5316\u901a\u77e5\u540e\u8c03\u7528\u66f4\u65b0\u51fd\u6570\u66f4\u65b0\u89c6\u56fe\u3002<\/li>\n<\/ul>\n<h2 id=\"mvvm-\u539f\u7406\u5b9e\u73b0\">MVVM \u539f\u7406\u5b9e\u73b0<\/h2>\n<p>\u4e3a\u4e86\u7406\u89e3 Vue MVVM \u5185\u90e8\u539f\u7406\uff0c\u8fd9\u91cc\u9020\u4e00\u4e2a\u7b80\u5355\u7684 MVVM \u4f2a\u8f6e\u5b50\uff0c\u80fd\u591f\u5b9e\u73b0\u6a21\u677f\u89e3\u6790\u3001\u6570\u636e\u54cd\u5e94\u5f0f\u7b49\u57fa\u672c\u529f\u80fd\uff0c\u5ffd\u7565\u7ec6\u8282\u548c\u660e\u663e\u7684 bug\u3002\u540c\u65f6\uff0c\u4e3a\u4e86\u66f4\u5bb9\u6613\u7406\u89e3\u548c\u66f4\u597d\u7684 coding \u4f53\u9a8c\uff0c\u4f7f\u7528\u73b0\u4ee3\u6d4f\u89c8\u5668\u652f\u6301\u7684 ES6+ \u8bed\u6cd5\u5b9e\u73b0\uff0c\u5212\u5206\u5404\u4e2a\u6a21\u5757\u3002<\/p>\n<p>\u8fd9\u4e2a\u8f6e\u5b50\u4e2d\u501f\u52a9 ES5 \u7684 <code>Object.defineProperty()<\/code> \u5b9e\u73b0\u6570\u636e\u52ab\u6301\uff1b\u5728<a href=\"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm-proxy\/\">\u4e0b\u4e00\u7bc7<\/a>\u4e2d\uff0c\u5c06\u4f1a\u4f7f\u7528 ES6 \u7684 <code>Proxy<\/code> \u5b9e\u73b0\uff0c\u8fd9\u4e5f\u662f Vue 3 \u7684\u8ba1\u5212\u4e4b\u4e00\u3002<\/p>\n<p>\u6548\u679c\uff1a<\/p>\n<!-- raw HTML omitted -->\n<h3 id=\"indexhtml\">index.html<\/h3>\n<!-- raw HTML omitted -->\n<p>\u5165\u53e3\u6587\u4ef6\uff0c\u521b\u5efa\u6e32\u67d3\u6a21\u677f\uff0c\u901a\u8fc7 <code>v-model<\/code> \u6307\u4ee4\u53cc\u5411\u7ed1\u5b9a <code>data<\/code>\uff0c\u540c\u7406 <code>v-class<\/code>\u3001<code>v-text<\/code>\u3001<code>v-html<\/code> \u6307\u4ee4\u63d2\u5165 <code>data<\/code> \u503c\uff0c<code>v-on:click<\/code> \u7ed1\u5b9a\u70b9\u51fb\u4e8b\u4ef6\u76d1\u542c\u5668 <code>method<\/code>\u3002<\/p>\n<p>\u5728 <code>module script<\/code> \u4e2d\u5bfc\u5165\u5e76\u5b9e\u4f8b\u5316 MVVM\uff0c\u5b9a\u4e49 <code>el<\/code>\u3001<code>data<\/code>\u3001<code>computed<\/code>\u3001<code>methods<\/code>\u3001<code>$watch<\/code> options\u3002<\/p>\n<h3 id=\"mvvm-\u6a21\u5757\">MVVM \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p>MVVM \u6784\u9020\u51fd\u6570\u4e2d\u628a <code>options.data<\/code>\u3001<code>options.computed<\/code>\u3001<code>options.methods<\/code> \u4e2d\u7684\u5c5e\u6027\u5168\u90e8\u7ed1\u5b9a\u5230 MVVM <code>this<\/code> \u4e0a\uff0c\u8fd9\u6837\u5c31\u80fd\u5728 <code>methods<\/code> \u4e2d\u901a\u8fc7 <code>this.xxx<\/code> \u4ee3\u7406\u5230\u5404\u81ea\u7684 key \u4e2d\uff0c\u6682\u65f6\u4e0d\u8003\u8651\u91cd\u590d\u7684 key\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><span class=\"lnt\">36\n<\/span><span class=\"lnt\">37\n<\/span><span class=\"lnt\">38\n<\/span><span class=\"lnt\">39\n<\/span><span class=\"lnt\">40\n<\/span><span class=\"lnt\">41\n<\/span><span class=\"lnt\">42\n<\/span><span class=\"lnt\">43\n<\/span><span class=\"lnt\">44\n<\/span><span class=\"lnt\">45\n<\/span><span class=\"lnt\">46\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ data \u4ee3\u7406\uff0c\u5b9e\u73b0 vm.xxx, this.xxx -&gt; vm.$data.xxx\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">_proxyData<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">$data<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span>\n  <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kr\">const<\/span> <span class=\"nx\">key<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">$data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nx\">defineProperty<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">configurable<\/span><span class=\"o\">:<\/span> <span class=\"kc\">false<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">enumerable<\/span><span class=\"o\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">get<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nx\">$data<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span>\n      <span class=\"p\">},<\/span>\n      <span class=\"nx\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">newVal<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">$data<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">newVal<\/span>\n      <span class=\"p\">},<\/span>\n    <span class=\"p\">})<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"c1\">\/\/ computed \u5c5e\u6027\u4ee3\u7406\uff0c\u5b9e\u73b0 vm.xxx, this.xxx -&gt; this.$options.computed.xxx\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">_proxyComputed<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">computed<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$options<\/span><span class=\"p\">.<\/span><span class=\"nx\">computed<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"k\">typeof<\/span> <span class=\"nx\">computed<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;object&#39;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kr\">const<\/span> <span class=\"nx\">key<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">computed<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nx\">defineProperty<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">get<\/span><span class=\"o\">:<\/span>\n        <span class=\"k\">typeof<\/span> <span class=\"nx\">computed<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;function&#39;<\/span>\n        <span class=\"o\">?<\/span> <span class=\"nx\">computed<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">]<\/span>\n        <span class=\"o\">:<\/span> <span class=\"nx\">computed<\/span><span class=\"p\">[<\/span><span class=\"nx\">key<\/span><span class=\"p\">].<\/span><span class=\"nx\">get<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">set<\/span><span class=\"o\">:<\/span> <span class=\"kd\">function<\/span><span class=\"p\">()<\/span> <span class=\"p\">{},<\/span>\n      <span class=\"p\">})<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"c1\">\/\/ \u7ed1\u5b9a options.methods \u7684\u65b9\u6cd5\u5230 this \u4e0a\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">_bindMethods<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">methods<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$options<\/span><span class=\"p\">.<\/span><span class=\"nx\">methods<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"k\">typeof<\/span> <span class=\"nx\">methods<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;object&#39;<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kr\">const<\/span> <span class=\"nx\">key<\/span> <span class=\"k\">in<\/span> <span class=\"nx\">methods<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nx\">defineProperty<\/span><span class=\"p\">(<\/span>\n        <span class=\"k\">this<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">key<\/span><span class=\"p\">,<\/span>\n        <span class=\"nb\">Object<\/span><span class=\"p\">.<\/span><span class=\"nx\">getOwnPropertyDescriptor<\/span><span class=\"p\">(<\/span><span class=\"nx\">methods<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">),<\/span>\n      <span class=\"p\">)<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u521d\u59cb\u5316 <code>this<\/code> \u4ee3\u7406\u540e\uff0c\u8c03\u7528 <code>Observer<\/code> \u52ab\u6301 <code>data<\/code> \u4e2d\u7684\u5168\u90e8\u5c5e\u6027\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">observe<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$data<\/span><span class=\"p\">,<\/span> <span class=\"k\">this<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u6700\u540e\uff0c\u8c03\u7528 <code>Compiler<\/code> \u89e3\u6790\u6a21\u677f\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">$compile<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nx\">Compiler<\/span><span class=\"p\">(<\/span><span class=\"nx\">options<\/span><span class=\"p\">.<\/span><span class=\"nx\">el<\/span> <span class=\"o\">||<\/span> <span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nx\">body<\/span><span class=\"p\">,<\/span> <span class=\"k\">this<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>MVVM \u5b9e\u4f8b\u4e5f\u63d0\u4f9b\u4e86 <code>$watch<\/code> \u65b9\u6cd5\uff0c\u8c03\u7528 <code>Watcher<\/code> \u76d1\u542c\u6307\u5b9a\u5c5e\u6027\u7684\u53d8\u5316\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">$watch<\/span><span class=\"p\">(<\/span><span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">cb<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">new<\/span> <span class=\"nx\">Watcher<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">,<\/span> <span class=\"nx\">key<\/span><span class=\"p\">,<\/span> <span class=\"nx\">cb<\/span><span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"dep-\u6a21\u5757\">Dep \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p><strong>Dep<\/strong> \u6a21\u5757\u4f5c\u4e3a<strong>\u53d1\u5e03-\u8ba2\u9605<\/strong>\u6a21\u5f0f\u7684\u8ba2\u9605\u4e2d\u5fc3\uff0c\u6bcf\u4e2a <code>data<\/code> \u4e2d\u7684\u5c5e\u6027(\u5305\u62ec\u5d4c\u5957) \u90fd\u7ed1\u5b9a\u4e86\u4e00\u4e2a <code>Dep<\/code> \u5b9e\u4f8b(\u901a\u8fc7\u95ed\u5305\u5f15\u7528)\uff0c\u63d0\u4f9b\u6dfb\u52a0\u3001\u901a\u77e5\u3001\u79fb\u9664\u8ba2\u9605\u8005\u7684\u63a5\u53e3\u3002<\/p>\n<p>\u4e00\u4e2a\u5c5e\u6027\u7ed1\u5b9a\u7684 <code>Dep<\/code> \u5b9e\u4f8b\u53ef\u4ee5\u5305\u542b\u591a\u4e2a\u8ba2\u9605\u8be5\u5c5e\u6027\u7684 <code>Watcher<\/code> \u5b9e\u4f8b\uff0c\u5c5e\u6027\u53d8\u5316\u540e\uff0c\u5c06\u901a\u77e5\u8fd9\u4e9b <code>Watcher<\/code> \u5b9e\u4f8b\u3002<\/p>\n<h3 id=\"observer-\u6a21\u5757\">Observer \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p><strong>Observer<\/strong> \u6a21\u5757\u4f9d\u8d56 <strong>Dep<\/strong> \u6a21\u5757\u3002<\/p>\n<p>Observer \u6784\u9020\u51fd\u6570\u9012\u5f52\u52ab\u6301 <code>data<\/code> \u4e2d\u7684\u5168\u90e8\u5c5e\u6027\uff0c\u5b9a\u4e49 getter \u548c setter\uff0c\u540c\u65f6\u4e3a\u6bcf\u4e2a\u5c5e\u6027\u7ed1\u5b9a\u4e00\u4e2a Dep \u5b9e\u4f8b\u3002<\/p>\n<p>\u5728\u5c5e\u6027\u7684 getter \u4e2d\u5224\u65ad\u5f53\u524d <code>Dep.target<\/code> \u662f\u5426\u6307\u5411\u4e00\u4e2a <code>Watcher<\/code> \u5b9e\u4f8b\uff0c\u5982\u679c\u662f\uff0c\u5219\u628a\u8be5 <code>Watcher<\/code> \u5b9e\u4f8b\u4f5c\u4e3a\u5c5e\u6027\u8ba2\u9605\u8005\u6dfb\u52a0\u5230 <code>Dep<\/code> \u4e2d\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">get<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ \u8bbf\u95ee\u8be5 key \u65f6\u5982\u679c Dep.target \u6307\u5411 Watcher \u5b9e\u4f8b\uff0c\u628a\u8be5 key \u5bf9\u5e94\u7684 Dep \u5b9e\u4f8b\u4f20\u9012\u7ed9 Watcher \u5b9e\u4f8b\n<\/span><span class=\"c1\"><\/span>  <span class=\"c1\">\/\/ \u4e5f\u53ef\u4ee5\u76f4\u63a5 dep.addSub(Dep.target)\n<\/span><span class=\"c1\"><\/span>  <span class=\"nx\">Dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">depend<\/span><span class=\"p\">()<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">val<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5728\u5c5e\u6027\u7684 setter \u4e2d\u5f53\u503c\u53d8\u5316\u540e\u901a\u8fc7\u95ed\u5305\u5f15\u7528\u7684 <code>Dep<\/code> \u5b9e\u4f8b\u901a\u77e5\u8ba2\u9605\u8005\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">set<\/span><span class=\"p\">(<\/span><span class=\"nx\">newVal<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">newVal<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">val<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"nx\">val<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">newVal<\/span>\n  <span class=\"c1\">\/\/ \u65b0\u7684\u503c\u662fobject\u7684\u8bdd\uff0c\u8fdb\u884c\u76d1\u542c\n<\/span><span class=\"c1\"><\/span>  <span class=\"nx\">observe<\/span><span class=\"p\">(<\/span><span class=\"nx\">newVal<\/span><span class=\"p\">)<\/span>\n  <span class=\"c1\">\/\/ \u901a\u77e5\u8ba2\u9605\u8be5 key \u7684 Watcher \u5b9e\u4f8b\n<\/span><span class=\"c1\"><\/span>  <span class=\"nx\">dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">notify<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"observer-named-export\">Observer named export<\/h4>\n<p><code>Observer<\/code> \u6a21\u5757\u5bfc\u51fa\u7684\u4e0d\u662f <code>Observer class<\/code>\uff0c\u800c\u662f <code>observe<\/code> \u51fd\u6570\uff0c\u7528\u4e8e\u9012\u5f52\u5b9e\u4f8b\u5316 <code>Observer<\/code> \u52ab\u6301\u5d4c\u5957\u7684 <code>data key<\/code> \u5bf9\u8c61\u3002\u76f8\u5f53\u4e8e <code>data<\/code> \u4e2d\u7684\u6bcf\u4e2a\u5d4c\u5957\u5bf9\u8c61\u90fd\u5bf9\u5e94\u4e00\u4e2a <code>Observer<\/code> \u5b9e\u4f8b\uff0c\u5305\u62ec <code>data<\/code> \u672c\u8eab\u3002\u4e0d\u8fc7\u5728\u8fd9\u4e2a\u8f6e\u5b50\u4e2d\u6ca1\u6709\u7528\u5230 <code>Observer<\/code> \u5b9e\u4f8b\u7684\u5f15\u7528\u3002<\/p>\n<h3 id=\"watcher-\u6a21\u5757\">Watcher \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p><strong>Watcher<\/strong> \u6a21\u5757\u4f9d\u8d56 <strong>Dep<\/strong> \u6a21\u5757\u3002<\/p>\n<p><code>Watcher<\/code> \u5728\u521d\u59cb\u5316\u65f6\u5c06\u4f1a\u628a <code>Dep.target<\/code> \u6307\u5411\u81ea\u8eab\u7684 <code>this<\/code>\uff0c\u7136\u540e\u8bbf\u95ee\u76d1\u542c\u7684\u5c5e\u6027\uff0c\u89e6\u53d1 <code>Observer<\/code> \u4e2d\u5b9a\u4e49\u7684\u5c5e\u6027 getter\uff0c\u4ece\u800c\u628a\u5f53\u524d <code>Watcher<\/code> \u5b9e\u4f8b\u6dfb\u52a0\u5230\u5c5e\u6027\u8ba2\u9605\u8005\u4e2d\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><span class=\"lnt\">8\n<\/span><span class=\"lnt\">9\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ \u83b7\u53d6 Wacher \u5b9e\u4f8b\u76d1\u89c6\u7684\u503c\n<\/span><span class=\"c1\"><\/span><span class=\"nx\">_getValue<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ \u8bbf\u95ee\u76d1\u542c\u7684\u5c5e\u6027\u65f6\u628a Dep.target \u6307\u5411\u81ea\u8eab\uff0c\u4ece\u800c\u5728 Observer \u4e2d\u628a\u5f53\u524d\u5b9e\u4f8b\u6dfb\u52a0\u5230\u5c5e\u6027\u8ba2\u9605\u8005\u4e2d\n<\/span><span class=\"c1\"><\/span>  <span class=\"nx\">Dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">value<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">getter<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">vm<\/span><span class=\"p\">)<\/span>\n  <span class=\"c1\">\/\/ \u83b7\u53d6\u5c5e\u6027\u503c\u540e\u7f6e\u7a7a Dep.target\n<\/span><span class=\"c1\"><\/span>  <span class=\"nx\">Dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">null<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">value<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"\u76d1\u542c\u5d4c\u5957\u5c5e\u6027\">\u76d1\u542c\u5d4c\u5957\u5c5e\u6027<\/h4>\n<p>\u5982\u679c <code>Watcher<\/code> \u5b9e\u4f8b\u76d1\u542c\u7684\u662f\u5d4c\u5957\u5c5e\u6027\uff0c\u6bd4\u5982 <code>a.b.c<\/code>\uff0c\u5173\u6ce8\u7684\u662f <code>c<\/code> \u503c\u7684\u53d8\u5316\u3002\u5219\u5728\u8bbf\u95ee <code>a<\/code> \u65f6\uff0c<code>a<\/code> \u7ed1\u5b9a\u7684 <code>Dep<\/code> \u5b9e\u4f8b\u4f1a\u628a\u5f53\u524d <code>Watcher<\/code> \u5b9e\u4f8b\u6dfb\u52a0\u5230\u8ba2\u9605\u8005\u4e2d\uff0c\u540c\u7406 <code>b<\/code>\u3001<code>c<\/code>\uff0c\u5373\u4e00\u4e2a <code>Watcher<\/code> \u5b9e\u4f8b\u7684\u5f15\u7528\u540c\u65f6\u5b58\u5728\u4e8e\u5d4c\u5957\u5c5e\u6027\u7684\u7236\u5c5e\u6027 <code>Dep<\/code> \u8ba2\u9605\u8005\u4e2d\uff1b\u5f53\u7236\u5c5e\u6027\u503c\u53d8\u5316\u65f6\uff0c\u4e5f\u4f1a\u901a\u77e5\u5230\u5b50\u5c5e\u6027\u7684\u8ba2\u9605\u8005\u3002<\/p>\n<h4 id=\"\u91cd\u590d\u7684-dep\">\u91cd\u590d\u7684 Dep<\/h4>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">applyDep<\/span><span class=\"p\">(<\/span><span class=\"nx\">dep<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">depIds<\/span><span class=\"p\">.<\/span><span class=\"nx\">hasOwnProperty<\/span><span class=\"p\">(<\/span><span class=\"nx\">dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">))<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">addSub<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">depIds<\/span><span class=\"p\">[<\/span><span class=\"nx\">dep<\/span><span class=\"p\">.<\/span><span class=\"nx\">id<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">dep<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5047\u5982\u76f8\u5e94\u5c5e\u6027\u7684 <code>dep.id<\/code> \u5df2\u7ecf\u5728\u5f53\u524d <code>watcher<\/code> \u7684 <code>depIds<\/code> \u91cc\uff0c\u8bf4\u660e\u4e0d\u662f\u4e00\u4e2a\u65b0\u7684\u5c5e\u6027\uff0c\u4ec5\u4ec5\u662f\u6539\u53d8\u4e86\u5176\u503c\u800c\u5df2\uff0c\u5219\u4e0d\u9700\u8981\u5c06\u5f53\u524d <code>watcher<\/code> \u6dfb\u52a0\u5230\u8be5\u5c5e\u6027\u7684 <code>dep<\/code> \u91cc\u3002<\/p>\n<p>\u5047\u5982\u76f8\u5e94\u5c5e\u6027\u662f\u65b0\u7684\u5c5e\u6027\uff0c\u5219\u5c06\u5f53\u524d <code>watcher<\/code> \u6dfb\u52a0\u5230\u65b0\u5c5e\u6027\u7684<code>dep<\/code>\u91cc\uff0c\u5982\u901a\u8fc7 <code>vm.child = {name: 'a'}<\/code> \u6539\u53d8\u4e86 <code>child.name<\/code> \u7684\u503c\uff0c<code>child.name<\/code> \u5c31\u662f\u4e2a\u65b0\u5c5e\u6027\uff0c\u5219\u9700\u8981\u5c06\u5f53\u524d<code>watcher(child.name)<\/code>\u52a0\u5165\u5230\u65b0\u7684 <code>child.name<\/code> \u7684<code>dep<\/code>\u91cc\u3002\u56e0\u4e3a\u6b64\u65f6 <code>child.name<\/code> \u662f\u4e2a\u65b0\u503c\uff0c\u4e4b\u524d\u7684 <code>setter<\/code>\u3001<code>dep<\/code> \u90fd\u5df2\u7ecf\u5931\u6548\uff0c\u5982\u679c\u4e0d\u628a <code>watcher<\/code> \u52a0\u5165\u5230\u65b0\u7684 <code>child.name<\/code> \u7684<code>dep<\/code>\u4e2d\uff0c\u901a\u8fc7 <code>child.name = xxx<\/code> \u8d4b\u503c\u7684\u65f6\u5019\uff0c\u5bf9\u5e94\u7684 <code>watcher<\/code> \u5c31\u6536\u4e0d\u5230\u901a\u77e5\uff0c\u7b49\u4e8e\u5931\u6548\u4e86\u3002<\/p>\n<h3 id=\"compiler-\u6a21\u5757\">Compiler \u6a21\u5757<\/h3>\n<!-- raw HTML omitted -->\n<p><strong>Compiler<\/strong> \u6a21\u5757\u4f9d\u8d56 <strong>Watcher<\/strong> \u6a21\u5757\u3002<\/p>\n<h4 id=\"documentfragment\">DocumentFragment<\/h4>\n<p><code>Compiler<\/code> \u5b9e\u4f8b\u5316\u65f6\u5148\u628a\u6a21\u677f\u8282\u70b9\u7684\u5b50\u8282\u70b9\u5168\u90e8\u8f6c\u79fb\u5230 <code>DocumentFragment<\/code> \u4e2d\u8fdb\u884c\u8282\u70b9\u64cd\u4f5c\uff0c\u907f\u514d\u9891\u7e41 reflow\uff0c\u5f71\u54cd\u6027\u80fd\uff1b\u5728\u6a21\u677f\u89e3\u6790\u5b8c\u540e\u518d\u628a <code>DocumentFragment<\/code> \u8f6c\u79fb\u5230\u6839\u8282\u70b9\u4e0b\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kd\">function<\/span> <span class=\"nx\">nodeToFragment<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">fragment<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nx\">createDocumentFragment<\/span><span class=\"p\">()<\/span>\n\n  <span class=\"c1\">\/\/ \u5c06\u539f\u751f\u8282\u70b9\u79fb\u52a8\u5230fragment\n<\/span><span class=\"c1\"><\/span>  <span class=\"kd\">let<\/span> <span class=\"nx\">child<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">node<\/span><span class=\"p\">.<\/span><span class=\"nx\">firstChild<\/span>\n  <span class=\"k\">while<\/span> <span class=\"p\">(<\/span><span class=\"nx\">child<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">fragment<\/span><span class=\"p\">.<\/span><span class=\"nx\">appendChild<\/span><span class=\"p\">(<\/span><span class=\"nx\">child<\/span><span class=\"p\">)<\/span>\n    <span class=\"nx\">child<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">node<\/span><span class=\"p\">.<\/span><span class=\"nx\">firstChild<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"nx\">fragment<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"\u6307\u4ee4\u89e3\u6790\">\u6307\u4ee4\u89e3\u6790<\/h4>\n<p><code>Compiler<\/code> \u89e3\u6790\u6a21\u677f\u4e2d\u7684 <code>v-<\/code> \u524d\u7f00\u7684\u6307\u4ee4\u548c <code>{{ exp }}<\/code> \u6587\u672c\u63d2\u503c\u8868\u8fbe\u5f0f\uff0c\u8be5\u8f6e\u5b50\u5ffd\u7565 <code>JavaScript<\/code> \u63d2\u503c\u8868\u8fbe\u5f0f\u3002\u80fd\u591f\u89e3\u6790\u7684\u6307\u4ee4\u6709 <code>v-model<\/code>\u3001 <code>v-class<\/code>\u3001<code>v-text<\/code>\u3001<code>v-html<\/code>\u3001<code>v-on<\/code>\uff0c\u8fd9\u4e9b\u6307\u4ee4\u90fd\u662f\u5f15\u7528 <code>data<\/code> \u4e2d\u7684\u5c5e\u6027\uff0c\u89e6\u53d1 <code>Observer<\/code> \u5b9a\u4e49\u7684 getter \u548c setter\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ \u6307\u4ee4\u5904\u7406\u96c6\u5408\n<\/span><span class=\"c1\"><\/span><span class=\"kr\">const<\/span> <span class=\"nx\">compilerUtils<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">text<\/span><span class=\"p\">()<\/span> <span class=\"p\">{},<\/span>\n  <span class=\"nx\">html<\/span><span class=\"p\">()<\/span> <span class=\"p\">{},<\/span>\n  <span class=\"c1\">\/\/ ...\n<\/span><span class=\"c1\"><\/span><span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"v-model-\u53cc\u5411\u7ed1\u5b9a\">v-model \u53cc\u5411\u7ed1\u5b9a<\/h4>\n<p><code>v-model<\/code> \u6307\u4ee4\u7ed1\u5b9a\u7684\u5c5e\u6027\uff0c<code>View<\/code> \u548c <code>Model<\/code> \u4e2d\u7684\u503c\u53d8\u5316\u4e92\u76f8\u5f71\u54cd\uff0c\u5373\u53cc\u5411\u7ed1\u5b9a\u3002<\/p>\n<p>\u76d1\u542c <code>v-model<\/code> \u6307\u4ee4\u6240\u5728\u7684 <code>node input<\/code> \u4e8b\u4ef6\uff0c<code>input<\/code> \u53d8\u5316\u540e\u901a\u8fc7 <code>vm.xxx<\/code> \u6539\u53d8\u5bf9\u5e94\u7684 <code>model<\/code> \u5c5e\u6027\u503c\uff0c\u89e6\u53d1\u8be5\u5c5e\u6027\u5b9a\u4e49\u7684 setter\uff0c\u5373\u5b9e\u73b0\u4e86 <code>View<\/code> \u5f71\u54cd <code>Model<\/code>\u3002<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">model<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">,<\/span> <span class=\"nx\">vm<\/span><span class=\"p\">,<\/span> <span class=\"nx\">exp<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">bind<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">,<\/span> <span class=\"nx\">vm<\/span><span class=\"p\">,<\/span> <span class=\"nx\">exp<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;model&#39;<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"kd\">let<\/span> <span class=\"nx\">val<\/span> <span class=\"o\">=<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_getVMVal<\/span><span class=\"p\">(<\/span><span class=\"nx\">vm<\/span><span class=\"p\">,<\/span> <span class=\"nx\">exp<\/span><span class=\"p\">)<\/span>\n  <span class=\"nx\">node<\/span><span class=\"p\">.<\/span><span class=\"nx\">addEventListener<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;input&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">e<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">newValue<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">val<\/span> <span class=\"o\">===<\/span> <span class=\"nx\">newValue<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">return<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_setVMVal<\/span><span class=\"p\">(<\/span><span class=\"nx\">vm<\/span><span class=\"p\">,<\/span> <span class=\"nx\">exp<\/span><span class=\"p\">,<\/span> <span class=\"nx\">newValue<\/span><span class=\"p\">)<\/span>\n    <span class=\"nx\">val<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">newValue<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"\u76d1\u542c\u5c5e\u6027\u53d8\u5316\">\u76d1\u542c\u5c5e\u6027\u53d8\u5316<\/h4>\n<p>\u6bcf\u4e2a\u6307\u4ee4\u5f15\u7528\u7684 <code>data<\/code> \u5c5e\u6027\u90fd\u9700\u8981\u5b9e\u4f8b\u5316 <code>Watcher<\/code> \u8fdb\u884c\u76d1\u542c\uff0c\u5e76\u540c\u65f6\u7ed1\u5b9a\u66f4\u65b0\u51fd\u6570\u7ed9 <code>Watcher<\/code> \u6536\u5230\u53d8\u5316\u901a\u77e5\u540e\u8c03\u7528\uff0c\u66f4\u65b0\u89c6\u56fe\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><span class=\"lnt\">8\n<\/span><span class=\"lnt\">9\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">bind<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">,<\/span> <span class=\"nx\">vm<\/span><span class=\"p\">,<\/span> <span class=\"nx\">exp<\/span><span class=\"p\">,<\/span> <span class=\"nx\">dir<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">updaterFn<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">updater<\/span><span class=\"p\">[<\/span><span class=\"nx\">dir<\/span> <span class=\"o\">+<\/span> <span class=\"s1\">&#39;Updater&#39;<\/span><span class=\"p\">]<\/span>\n\n  <span class=\"nx\">updaterFn<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">updaterFn<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">,<\/span> <span class=\"k\">this<\/span><span class=\"p\">.<\/span><span class=\"nx\">_getVMVal<\/span><span class=\"p\">(<\/span><span class=\"nx\">vm<\/span><span class=\"p\">,<\/span> <span class=\"nx\">exp<\/span><span class=\"p\">))<\/span>\n\n  <span class=\"k\">new<\/span> <span class=\"nx\">Watcher<\/span><span class=\"p\">(<\/span><span class=\"nx\">vm<\/span><span class=\"p\">,<\/span> <span class=\"nx\">exp<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">oldValue<\/span><span class=\"p\">)<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">updaterFn<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">updaterFn<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">,<\/span> <span class=\"nx\">oldValue<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h4 id=\"\u5c5e\u6027\u503c\u66f4\u65b0\">\u5c5e\u6027\u503c\u66f4\u65b0<\/h4>\n<p>\u76d1\u542c\u7684\u5c5e\u6027\u503c\u53d8\u5316\u540e\uff0c\u6bcf\u4e2a\u6307\u4ee4\u90fd\u5bf9\u5e94\u4e0d\u540c\u7684\u66f4\u65b0\u64cd\u4f5c\uff0c\u6bd4\u5982\u66ff\u6362 <code>textContent<\/code>\u3001<code>innerHTML<\/code>\u3001<code>value<\/code> \u7b49\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"kr\">const<\/span> <span class=\"nx\">updater<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">textUpdater<\/span><span class=\"p\">(<\/span><span class=\"nx\">node<\/span><span class=\"p\">,<\/span> <span class=\"nx\">value<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">node<\/span><span class=\"p\">.<\/span><span class=\"nx\">textContent<\/span> <span class=\"o\">=<\/span> <span class=\"k\">typeof<\/span> <span class=\"nx\">value<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">&#39;undefined&#39;<\/span> <span class=\"o\">?<\/span> <span class=\"s1\">&#39;&#39;<\/span> <span class=\"o\">:<\/span> <span class=\"nx\">value<\/span>\n  <span class=\"p\">},<\/span>\n  <span class=\"nx\">htmlUpdater<\/span><span class=\"p\">()<\/span> <span class=\"p\">{}<\/span>\n  <span class=\"c1\">\/\/ ...\n<\/span><span class=\"c1\"><\/span><span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5728\u8fd9\u4e2a\u8f6e\u5b50\u4e2d\uff0c\u66f4\u65b0 DOM \u662f\u540c\u6b65\u6267\u884c\u7684\uff0c\u800c\u4e14\u4e0d\u6d89\u53ca Virtual DOM\u3002\u5728 Vue \u4e2d\u4f1a\u5bf9 Virtual DOM \u66f4\u65b0\u7136\u540e\u7f13\u5b58\u5728\u5f02\u6b65\u66f4\u65b0\u961f\u5217\uff0c\u5728\u4e0b\u4e00\u4e2a\u4e8b\u4ef6\u5faa\u73af <strong>tick<\/strong> \u4e2d flush \u5230 DOM\u3002<\/p>\n<h3 id=\"\u56de\u987e\">\u56de\u987e<\/h3>\n<p><strong>MVVM<\/strong> \u6a21\u5f0f\u964d\u4f4e\u4e86 <strong>View<\/strong> \u4e0e <strong>Model<\/strong> \u7684\u8026\u5408\uff0c\u7531 <strong>ViewModel<\/strong> \u81ea\u52a8\u5904\u7406 View \u4e0e Model \u7684\u6570\u636e\u540c\u6b65\uff0c\u89e3\u51b3\u4e86\u6570\u636e\u9891\u7e41\u66f4\u65b0\uff08\u64cd\u4f5c DOM\uff09\u7684\u95ee\u9898\u3002View \u901a\u8fc7\u4f7f\u7528<strong>\u6a21\u677f\u8bed\u6cd5<\/strong>\u6765<strong>\u58f0\u660e\u5f0f<\/strong>\u7684\u5c06\u6570\u636e\u6e32\u67d3\u8fdb DOM\uff0c\u5f53 ViewModel \u5bf9 Model \u8fdb\u884c\u66f4\u65b0\u7684\u65f6\u5019\uff0c\u4f1a\u901a\u8fc7\u6570\u636e\u7ed1\u5b9a\u66f4\u65b0\u5230 View\u3002Model (\u5728\u672c\u6587\u4e2d\u5c31\u662f <code>data<\/code>) \u4ec5\u4ec5\u5173\u6ce8\u6570\u636e\u5c42\u672c\u8eab\uff0c\u4e0d\u5173\u5fc3\u4efb\u4f55\u884c\u4e3a\uff1bModel \u7684\u6570\u636e\u6a21\u578b\u7ed3\u5408\u89c6\u56fe\u548c\u4e1a\u52a1\u5b9e\u4f53\u3002<\/p>\n<p><del>\u5ba0\u7740<\/del>\uff0c\u753b\u4e86\u4e2a\u5404\u6a21\u5757\u7684\u5173\u7cfb\u56fe\u5e2e\u52a9\u7406\u89e3\uff1a<\/p>\n<p><img src=\"https:\/\/lg-gxg3fdgs-1254198195.cos.ap-shanghai.myqcloud.com\/blog\/2019-04-26-084701.png\" alt=\"image-20190426164700940\"><\/p>\n<p>\u6700\u540e\uff0c\u672c\u8f6e\u5b50 GitHub \u5730\u5740\uff1a<a href=\"https:\/\/github.com\/Jancat\/vue-mvvm\">https:\/\/github.com\/Jancat\/vue-mvvm<\/a><\/p>\n<p><strong>Follow<\/strong> or <strong>Star<\/strong>\uff0c\u4f60\u9009\u54ea\u4e2a\uff1f<\/p>\n<p>\uff08<del>\u4e0d\uff0c\u5c0f\u5b69\u5b50\u624d\u505a\u9009\u62e9\uff0c\u5927\u4eba\u5168\u90fd\u8981<\/del>\uff09<\/p>\n<h2 id=\"\u5b89\u5229\">\u5b89\u5229<\/h2>\n<p>\u5b89\u5229\u4e00\u6ce2\u672c\u6587\u4e2d\u4f7f\u7528\u5230\u7684\u5de5\u5177\uff1a<\/p>\n<ul>\n<li><a href=\"https:\/\/codesandbox.io\">CodeSandbox<\/a> : \u57fa\u4e8e VSCode \u7f16\u8f91\u5668\u7684 <strong>Cloud IDE<\/strong>\uff0c\u5185\u7f6e\u5404\u79cd\u6d41\u884c\u6846\u67b6\u6a21\u677f\u3002\u901a\u8fc7 <code>&lt;iframe&gt;<\/code> \u63d0\u4f9b <strong>embed<\/strong> \u7684\u9879\u76ee\u3001\u4ee3\u7801\u9884\u89c8\uff0c\u65b9\u4fbf\u7684\u5d4c\u5165\u6587\u7ae0\u4e2d\uff0c\u4e43\u5c55\u793a\u6548\u679c\u3001\u9879\u76ee\u4ee3\u7801\u7684\u884c\u6587\u5229\u5668\u3002<\/li>\n<li><a href=\"https:\/\/www.processon.com\">ProcessOn<\/a>\uff1a\u5728\u7ebf\u7ed8\u5236\u601d\u7ef4\u5bfc\u56fe\u3001\u6d41\u7a0b\u56fe\u7b49\uff0cUI \u7f8e\u89c2\uff0c\u6548\u679c\u62d4\u7fa4\u3002\u4e0d\u8fc7\u514d\u8d39\u7248\u6709\u6587\u4ef6\u6570\u91cf\u9650\u5236\u3002<\/li>\n<\/ul>\n<h2 id=\"\u53c2\u8003\">\u53c2\u8003<\/h2>\n<p>\u672c\u8f6e\u5b50\u57fa\u4e8e\u4e0b\u9762\u7684\u4ed3\u5e93\u4ee3\u7801\u6539\u9020\uff0c\u611f\u8c22\uff01<\/p>\n<p><a href=\"https:\/\/github.com\/DMQ\/mvvm\">https:\/\/github.com\/DMQ\/mvvm<\/a><\/p>\n<hr>\n<p><strong>\u5144\u5f1f\u7bc7<\/strong>\uff1a<a href=\"https:\/\/jancat.github.io\/post\/2019\/vue-mvvm-proxy\/\">Vue MVVM \u5b9e\u73b0\uff08Proxy \u7bc7\uff09<\/a><\/p>"},{"title":"\u4f7f\u7528 Elementary OS","link":"https:\/\/jancat.github.io\/post\/2018\/use-elementary-os\/","pubDate":"Sun, 08 Jul 2018 18:16:57 +0800","guid":"https:\/\/jancat.github.io\/post\/2018\/use-elementary-os\/","description":"<p><a href=\"https:\/\/jancat.github.io\/post\/2018\/win10-vmware-install-elementary-os\/\">\u4e0a\u4e00\u7bc7<\/a> \u4ecb\u7ecd\u4e86\u5728 Win10 \u4e0a\u5b89\u88c5 Elementary OS\uff0c\u8fd9\u7bc7\u4ecb\u7ecd\u4e0b Elementary OS \u7684\u7b80\u5355\u4f7f\u7528\u3002<\/p>\n<p><img src=\"https:\/\/jancat.github.io\/images\/post\/use-elementary-os\/elementary-desktop.png\" alt=\"elementary-desktop\"><\/p>\n<h2 id=\"\u5305\u7ba1\u7406-apt-get\">\u5305\u7ba1\u7406 apt-get<\/h2>\n<p>\u56e0\u4e3a Elementary OS \u662f\u57fa\u4e8e Ubuntu \u7684 Linux \u53d1\u884c\u7248\uff0c\u800c Ubuntu \u53c8\u662f\u57fa\u4e8e Debian\uff0c\u6240\u6709\u57fa\u4e8e Debian \u7684\u53d1\u884c\u7248\u90fd\u4f7f\u7528 <code>apt-get<\/code> \u8fd9\u4e2a\u5305\u7ba1\u7406\u7cfb\u7edf\u3002deb \u5305\u53ef\u4ee5\u628a\u4e00\u4e2a\u5e94\u7528\u7684\u6587\u4ef6\u5305\u5728\u4e00\u8d77\uff0c\u5927\u4f53\u5c31\u5982\u540c Windows \u4e0a\u7684\u5b89\u88c5\u6587\u4ef6\u3002<\/p>\n<p>\u4f7f\u7528 <code>apt-get<\/code> \u547d\u4ee4\u7684\u7b2c\u4e00\u6b65\u5c31\u662f\u5f15\u5165\u5fc5\u9700\u7684\u8f6f\u4ef6\u5e93\uff0cDebian \u7684\u8f6f\u4ef6\u5e93\u4e5f\u5c31\u662f Debian \u8f6f\u4ef6\u5305\u7684\u96c6\u5408\uff0c\u5b83\u4eec\u5b58\u5728\u4e92\u8054\u7f51\u4e0a\u7684\u4e00\u4e9b\u516c\u5171\u7ad9\u70b9\u4e0a\u3002\u628a\u5b83\u4eec\u7684\u5730\u5740\u5f15\u5165\u540e\uff0c<code>apt-get<\/code> \u5c31\u80fd\u641c\u7d22\u5230\u6211\u4eec\u60f3\u8981\u7684\u8f6f\u4ef6\u3002<code>\/etc\/apt\/sources.list<\/code> \u662f\u5b58\u653e\u8fd9\u4e9b\u5730\u5740\u5217\u8868\u7684\u914d\u7f6e\u6587\u4ef6\uff0c\u5176\u683c\u5f0f\u5982\u4e0b\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">deb <span class=\"o\">[<\/span>web\u6216ftp\u5730\u5740<span class=\"o\">]<\/span> <span class=\"o\">[<\/span>\u53d1\u884c\u7248\u540d\u5b57<span class=\"o\">]<\/span> <span class=\"o\">[<\/span>main\/contrib\/non-free<span class=\"o\">]<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5728\u4fee\u6539 <code>\/etc\/apt\/sources.list<\/code> \u4e4b\u540e\u9700\u8981\u6267\u884c <code>sudo apt-get update<\/code> \u6765\u66f4\u65b0\u672c\u5730\u5305\u5217\u8868\u3002<\/p>\n<h3 id=\"\u66ff\u6362\u4e3a-\u963f\u91cc\u4e91\u6e90\">\u66ff\u6362\u4e3a \u963f\u91cc\u4e91\u6e90<\/h3>\n<p>Elementary OS \u7684\u8f6f\u4ef6\u6e90\u9ed8\u8ba4\u4e3a\u56fd\u5916\u7684\u6e90\uff0c\u901f\u5ea6\u8f83\u6162\uff0c\u53ef\u4ee5\u66f4\u6362\u4e3a\u56fd\u5185\u901f\u5ea6\u8f83\u5feb\u7684\u963f\u91cc\u4e91\u8f6f\u4ef6\u6e90\uff1a<\/p>\n<ol>\n<li>\n<p>\u5728\u7ec8\u7aef\u4e0b\u4fee\u6539 <code>\/etc\/apt\/sources.list<\/code> \u6587\u4ef6\u7684\u53ef\u5199\u6743\u9650\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo chmod a+w \/etc\/apt\/source.list\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u5907\u4efd <strong>source.list<\/strong><\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo cp \/etc\/apt\/source.list \/etc\/apt\/source.list.bak\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u5728 <strong>Scratch<\/strong> \u6587\u672c\u7f16\u8f91\u5668\u4e2d\u6253\u5f00 <code>\/etc\/apt\/source.list<\/code><\/p>\n<\/li>\n<li>\n<p>\u5220\u9664\u539f\u6709\u5185\u5bb9\uff0c\u66ff\u6362\u4e3a <strong>\u963f\u91cc\u4e91\u6e90<\/strong><\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-txt\" data-lang=\"txt\">deb http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty main restricted universe multiverse\ndeb http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-security main restricted universe multiverse\ndeb http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-updates main restricted universe multiverse\ndeb http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-proposed main restricted universe multiverse\ndeb http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-backports main restricted universe multiverse\ndeb-src http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty main restricted universe multiverse\ndeb-src http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-security main restricted universe multiverse\ndeb-src http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-updates main restricted universe multiverse\ndeb-src http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-proposed main restricted universe multiverse\ndeb-src http:\/\/mirrors.aliyun.com\/ubuntu\/ trusty-backports main restricted universe multiverse\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u6267\u884c\u66f4\u65b0<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt-get update\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<\/ol>\n<h2 id=\"\u5e38\u7528\u8f6f\u4ef6\u5b89\u88c5\">\u5e38\u7528\u8f6f\u4ef6\u5b89\u88c5<\/h2>\n<h3 id=\"\u641c\u72d7\u62fc\u97f3\u8f93\u5165\u6cd5\">\u641c\u72d7\u62fc\u97f3\u8f93\u5165\u6cd5<\/h3>\n<p>Linux \u7cfb\u7edf\u8ddf\u5e94\u7528\u7a0b\u5e8f\u6253\u4ea4\u9053\u7684\u662f\u8f93\u5165\u6cd5\u6846\u67b6\uff0c\u5176\u4e2d IBus \u662f\u76ee\u524d\u4e3b\u6d41\u53d1\u884c\u7248\u7684\u9ed8\u8ba4\u914d\u7f6e\u3002\u5404\u79cd\u8f93\u5165\u6cd5\u8981\u6709\u76f8\u5bf9\u5e94\u7684\u8f93\u5165\u6cd5\u6846\u67b6\u652f\u6301\uff0c\u4e2d\u6587\u8f93\u5165\u6cd5\u662f\u57fa\u4e8e <strong>fcitx<\/strong> \u7684\uff0c\u800c\u7cfb\u7edf\u9ed8\u8ba4\u7684\u662f iBus\uff0c\u6240\u4ee5\u8981\u5148\u5b89\u88c5 <strong>fcitx \u4e2d\u6587\u8f93\u5165\u6cd5\u6846\u67b6<\/strong>\u3002<\/p>\n<h4 id=\"\u5b89\u88c5-fcitx\">\u5b89\u88c5 fcitx<\/h4>\n<ol>\n<li>\n<p>\u5b89\u88c5\u7b2c\u4e09\u65b9\u8f6f\u4ef6\u6e90 <code>software-properties-common<\/code> \u548c <code>python-software-properties<\/code><\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt-get install software-properties-common python-software-properties\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u6dfb\u52a0 <strong>ppa<\/strong> \u6e90<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo add-apt-repository ppa:fcitx-team\/nightly\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u66f4\u65b0\u8f6f\u4ef6<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt-get update\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u5b89\u88c5 fcitx<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt-get install fcitx \n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u5b89\u88c5 fcitx \u7684\u914d\u7f6e\u5de5\u5177\u3001table-all \u8f6f\u4ef6\u5305\u3001fcitx-table-all\u3001im-config \u5207\u6362\u5de5\u5177<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt-get install fcitx-config-gtk fcitx-table-all im-config\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u4fee\u590d\u8f6f\u4ef6\u4f9d\u8d56<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt-get -f install\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u9a8c\u8bc1 fcitx \u662f\u5426\u5b89\u88c5\u6210\u529f\uff0c\u5728 <strong>Applications<\/strong> \u4e2d\u67e5\u770b\u662f\u5426\u6709 fcitx \u7684\u5e94\u7528\u56fe\u6807<\/p>\n<\/li>\n<\/ol>\n<h4 id=\"\u5b89\u88c5\u641c\u72d7\u62fc\u97f3\u8f93\u5165\u6cd5\">\u5b89\u88c5\u641c\u72d7\u62fc\u97f3\u8f93\u5165\u6cd5<\/h4>\n<ol>\n<li>\u5728 <a href=\"https:\/\/pinyin.sogou.com\/linux\/?r=pinyin\">\u641c\u72d7\u5b98\u7f51<\/a> \u4e0b\u8f7d\u8f93\u5165\u6cd5 Linux \u7248 64\u4f4d<\/li>\n<li>\u5728\u4e0b\u8f7d\u76ee\u5f55\u4e2d\u4f7f\u7528 <code>dpkg<\/code> \u547d\u4ee4\u5b89\u88c5 deb \u5305\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo dpkg -i sougoupinyin-xxx.deb\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\u66f4\u65b0\u5305\u4f9d\u8d56\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt -f install -y\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\u91cd\u542f\u7cfb\u7edf<\/li>\n<li>\u5728\u7ec8\u7aef\u4e2d\u8f93\u5165 <code>im-config<\/code>\uff0c\u6253\u5f00 <strong>Input Method Configuration<\/strong> \u8f93\u5165\u6cd5\u914d\u7f6e\u754c\u9762<\/li>\n<li>\u786e\u5b9a\u9ed8\u8ba4\u8f93\u5165\u6cd5\u4e3a <strong>\u641c\u72d7\u62fc\u97f3<\/strong><\/li>\n<li>\u5728\u684c\u9762\u53f3\u4e0a\u89d2\u4e2d\u542f\u7528\u641c\u72d7\u8f93\u5165\u6cd5\n<img src=\"https:\/\/jancat.github.io\/images\/post\/use-elementary-os\/sougou-pinyin.jpg\" alt=\"sougou-pinyin\"><\/li>\n<\/ol>\n<h3 id=\"chrome\">Chrome<\/h3>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo apt-get install google-chrome-stable\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h3 id=\"monitor\">Monitor<\/h3>\n<p>\u8fdb\u7a0b\u7ba1\u7406\u5de5\u5177\uff0c\u5728 App Center \u4e2d\u641c\u7d22 <strong>Monitor<\/strong><\/p>\n<h3 id=\"albert\">Albert<\/h3>\n<p>Alfred in Elementary os\n\u5feb\u901f\u641c\u7d22\u3001\u542f\u52a8\u5e94\u7528\u795e\u5668<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo add-apt-repository ppa:nilarimogard\/webupd8\nsudo apt update\nsudo apt install albert\n\nsudo apt -f install\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><h2 id=\"\u7cfb\u7edf\u8bbe\u7f6e\">\u7cfb\u7edf\u8bbe\u7f6e<\/h2>\n<h4 id=\"dock-\u8bbe\u7f6e\u4f4d\u7f6e\u56fe\u6807\">Dock \u8bbe\u7f6e\uff08\u4f4d\u7f6e\u3001\u56fe\u6807\uff09<\/h4>\n<p>\u7ec8\u7aef\u6267\u884c <code>plank --preferences<\/code><\/p>\n<h2 id=\"\u5e38\u89c1\u95ee\u9898\">\u5e38\u89c1\u95ee\u9898<\/h2>\n<h3 id=\"dpkg-\u6587\u4ef6\u88ab\u9501\u5176\u5b83\u8fdb\u7a0b\u6b63\u5728\u5360\u7528\">dpkg \u6587\u4ef6\u88ab\u9501\uff0c\u5176\u5b83\u8fdb\u7a0b\u6b63\u5728\u5360\u7528<\/h3>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">E: Could not open lock file \/var\/lib\/dpkg\/lock - open <span class=\"o\">(<\/span>13: Permission denied<span class=\"o\">)<\/span>\nE: Unable to lock the administration directory <span class=\"o\">(<\/span>\/var\/lib\/dpkg\/<span class=\"o\">)<\/span>, are you root?\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><strong>\u89e3\u51b3\uff1a<\/strong> \u5220\u9664\u6587\u4ef6\u9501<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo rm \/var\/cache\/apt\/archives\/lock\nsudo rm \/var\/lib\/dpkg\/lock\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><hr>\n<h3 id=\"unable-to-locate-package\">Unable to locate package<\/h3>\n<p>\u6267\u884c <code>sudo apt-get update<\/code><\/p>\n<hr>\n<h3 id=\"could-not-get-lock-\u65e0\u6cd5\u9501\u6587\u4ef6\">Could not get lock \u65e0\u6cd5\u9501\u6587\u4ef6<\/h3>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">E: Could not get lock \/var\/lib\/apt\/lists\/lock - open <span class=\"o\">(<\/span>11: Resource temporarily unavailable<span class=\"o\">)<\/span>\nE: Unable to lock directory \/var\/lib\/apt\/lists\/\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p><strong>\u539f\u56e0\uff1a<\/strong> \u6587\u4ef6\u9501\u51b2\u7a81\n<strong>\u89e3\u51b3\uff1a<\/strong><\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">sudo rm \/var\/lib\/apt\/lists\/lock\nsudo apt-get update\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><hr>\n<h3 id=\"w-\u65e0\u6cd5\u4e0b\u8f7d-httpppalaunchpadnetfcitx-teamnightlyubuntudistsjessiemainbinary-amd64packages\">W: \u65e0\u6cd5\u4e0b\u8f7d <a href=\"http:\/\/ppa.launchpad.net\/fcitx-team\/nightly\/ubuntu\/dists\/jessie\/main\/binary-amd64\/Packages\">http:\/\/ppa.launchpad.net\/fcitx-team\/nightly\/ubuntu\/dists\/jessie\/main\/binary-amd64\/Packages<\/a><\/h3>\n<p><strong>\u89e3\u51b3\uff1a<\/strong> \u6267\u884c\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"nb\">cd<\/span> \/etc\/apt\/sources.list.d\nsudo mv xx.list xx.list.bak\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div>"},{"title":"Win10 VMware \u5b89\u88c5 Elementary OS","link":"https:\/\/jancat.github.io\/post\/2018\/win10-vmware-install-elementary-os\/","pubDate":"Sat, 21 Apr 2018 10:59:40 +0800","guid":"https:\/\/jancat.github.io\/post\/2018\/win10-vmware-install-elementary-os\/","description":"<p><img src=\"https:\/\/jancat.github.io\/images\/post\/win10-vmware-install-elementary-os\/elementary-os-poster.jpg\" alt=\"Elementary OS Poster\"><\/p>\n<blockquote>\n<p>elementary OS\u662f\u4e00\u4e2a\u57fa\u4e8eUbuntu\u7684Linux\u53d1\u884c\u7248\u3002\u5b83\u4f7f\u7528\u4e00\u4e2a\u81ea\u5df1\u5f00\u53d1\u7684\u57fa\u4e8eGNOME\u7684\u540d\u4e3aPantheon\u7684\u684c\u9762\u73af\u5883\u3002 \u8fd9\u4e2a\u684c\u9762\u73af\u5883\u51fa\u4f17\u7684\u539f\u56e0\u662f\u5b83\u6df1\u5ea6\u96c6\u6210\u4e86\u5176\u4ed6elementary OS\u5e94\u7528\u7a0b\u5e8f\uff0c\u5982Plank\uff08\u4e00\u4e2a\u57fa\u4e8eDocky\u7684Dock\uff09\u3001Midori\uff08\u9ed8\u8ba4\u7684\u7f51\u9875\u6d4f\u89c8\u5668\uff09\u6216Scratch\uff08\u4e00\u4e2a\u7b80\u5355\u7684\u6587\u672c\u7f16\u8f91\u5668\uff09\u3002\u8be5\u53d1\u884c\u7248\u4f7f\u7528\u57fa\u4e8eMutter\u7684Gala\u4f5c\u4e3a\u5176\u7a97\u53e3\u7ba1\u7406\u5668\u3002<\/p>\n<p>\u8fd9\u4e2a\u53d1\u884c\u7248\u662f\u4ece\u4e3aUbuntu\u8bbe\u8ba1\u7684\u4e00\u5957\u4e3b\u9898\u548c\u5e94\u7528\u7a0b\u5e8f\u53d1\u5c55\u800c\u6765\u7684\u3002\u7531\u4e8e\u662f\u57fa\u4e8eUbuntu\u7684\uff0c\u56e0\u6b64\u4e0eUbuntu\u7684\u4ed3\u5e93\u548c\u5305\u5b8c\u5168\u517c\u5bb9\u3002\u5b83\u4f7f\u7528Ubuntu\u81ea\u5df1\u7684\u8f6f\u4ef6\u4e2d\u5fc3\u6765\u5904\u7406\u8f6f\u4ef6\u7684\u5b89\u88c5\u548c\u5378\u8f7d\u3002\u5176\u7c7b\u4f3c\u4e8eMac OS X\u7684\u754c\u9762\u81f4\u529b\u4e8e\u4f7f\u65b0\u7528\u6237\u4e0d\u9700\u8981\u8d39\u592a\u5927\u529b\u6c14\u5c31\u53ef\u4ee5\u6839\u636e\u76f4\u89c9\u4f7f\u7528\u3002\n\u2014\u2014 <a href=\"https:\/\/zh.wikipedia.org\/wiki\/Elementary_OS\">elementary OS wiki<\/a><\/p>\n<\/blockquote>\n<p>2018\u5e74\uff0c<strong>elementary OS<\/strong> \u6709\u6587\u7ae0\u8bc4\u4ef7\u4e3a\u201c<strong>\u6700\u7f8e\u7684Linux\u684c\u9762\u53d1\u884c\u7248<\/strong>\u201d\uff0c\u5176\u684c\u9762\u73af\u5883\u548c\u4f7f\u7528\u8ddf Mac OS X \u5f88\u76f8\u4f3c\uff1b\u5982\u679c\u4f60\u60f3\u5728 Windows \u4e0b\u62e5\u6709 Mac \u7cfb\u7edf\u7684\u64cd\u4f5c\u4f53\u9a8c\uff0c\u90a3\u4e48\u5728\u865a\u62df\u673a\u4e2d\u5b89\u88c5 elementary os \u662f\u4e2a\u6700\u597d\u7684\u9009\u62e9\uff0c\u53ef\u4ee5\u968f\u65f6\u5728 Windows \u529e\u516c\u5a31\u4e50\u3001elementary OS \u5f00\u53d1\u73af\u5883\u4e4b\u95f4\u5207\u6362\u3002<\/p>\n<p>\u672c\u6587\u5c06\u4e00\u6b65\u6b65\u4ecb\u7ecd\u5728 Win10 VMware \u4e2d\u5b89\u88c5 elementary OS \u7684\u6b65\u9aa4\u3002<\/p>\n<h3 id=\"\u4e0b\u8f7d-elementary-os-\u955c\u50cf\">\u4e0b\u8f7d Elementary OS \u955c\u50cf<\/h3>\n<ol>\n<li>\u8fdb\u5165\u5b98\u7f51 <a href=\"https:\/\/elementary.io\/zh_CN\/\">https:\/\/elementary.io\/zh_CN\/<\/a><\/li>\n<li>\u8f93\u5165\u91d1\u989d 0\uff0c\u70b9\u51fb\u4e0b\u8f7d iso \u955c\u50cf\n<img src=\"https:\/\/jancat.github.io\/images\/post\/win10-vmware-install-elementary-os\/download-elementary-os-iso.png\" alt=\"download-elementary-os-iso\"><\/li>\n<\/ol>\n<h3 id=\"\u4e0b\u8f7d\u5b89\u88c5-vmware-workstation-pro\">\u4e0b\u8f7d\u5b89\u88c5 VMware Workstation Pro<\/h3>\n<ol>\n<li>\u8fdb\u5165 VMware \u5b98\u7f51\u4e0b\u8f7d\u9875\u9762\u4e0b\u8f7d <a href=\"https:\/\/my.vmware.com\/en\/web\/vmware\/info\/slug\/desktop_end_user_computing\/vmware_workstation_pro\/14_0\">https:\/\/my.vmware.com\/en\/web\/vmware\/info\/slug\/desktop_end_user_computing\/vmware_workstation_pro\/14_0<\/a><\/li>\n<li>\u5b89\u88c5<\/li>\n<li>\u8f93\u5165\u5e8f\u5217\u53f7\u6fc0\u6d3b <code>CV7T2-6WY5Q-48EWP-ZXY7X-QGUWD<\/code>\u3001<code>FF31K-AHZD1-H8ETZ-8WWEZ-WUUVA<\/code><\/li>\n<\/ol>\n<h3 id=\"\u521b\u5efa-elementary-os-\u865a\u62df\u673a\">\u521b\u5efa elementary OS \u865a\u62df\u673a<\/h3>\n<ol>\n<li>\n<p>\u542f\u52a8 VMware<\/p>\n<\/li>\n<li>\n<p>\u521b\u5efa\u65b0\u7684\u865a\u62df\u673a\uff0c\u9009\u62e9<strong>\u81ea\u5b9a\u4e49<\/strong>\uff0c\u4e0b\u4e00\u6b65<\/p>\n<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\n<p>\u9009\u62e9\u865a\u62df\u673a\u517c\u5bb9\u6027\uff0c\u9ed8\u8ba4\u4e0b\u4e00\u6b65<\/p>\n<\/li>\n<li>\n<p>\u9009\u62e9<strong>\u5b89\u88c5\u7a0b\u5e8f\u5149\u76d8\u6620\u50cf\u6587\u4ef6<\/strong>\uff0c\u9009\u4e2d\u521a\u624d\u4e0b\u8f7d\u7684 Elementary OS iso\u955c\u50cf\u6587\u4ef6\uff0c\u4e0b\u4e00\u6b65<\/p>\n<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u64cd\u4f5c\u7cfb\u7edf\u7248\u672c\u9009\u62e9 <strong>Linux<\/strong>\u3001<strong>\u5176\u4ed6 Linux 4.x \u6216\u66f4\u9ad8\u7248\u672c\u5185\u6838 64\u4f4d<\/strong>\uff0c\u4e0b\u4e00\u6b65<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u4fee\u6539\u9ed8\u8ba4\u7684\u865a\u62df\u673a\u540d\u79f0\u548c\u5b58\u50a8\u4f4d\u7f6e\uff0c\u4e0b\u4e00\u6b65<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u5904\u7406\u5668\u914d\u7f6e2\u6838\uff08\u5f53\u524d\u64cd\u4f5c\u7cfb\u7edf\u5185\u6838\u6570\u7684\u4e00\u534a\uff09\uff0c\u4e0b\u4e00\u6b65<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u5185\u5b58\u770b\u4e2a\u4eba\u9009\u62e9\uff0c\u8fd9\u91cc\u9009\u62e93G\uff0c\u4e0b\u4e00\u6b65<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u7f51\u7edc\u7c7b\u578b\u9009\u62e9 <strong>\u6865\u63a5\u7f51\u7edc<\/strong>\uff0c\u4e0b\u4e00\u6b65<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\n<p>\u9009\u62e9I\/O\u63a7\u5236\u5668\u7c7b\u578b\uff0c\u9ed8\u8ba4\u4e0b\u4e00\u6b65<\/p>\n<\/li>\n<li>\n<p>\u9009\u62e9\u786c\u76d8\u7c7b\u578b\uff0c\u9ed8\u8ba4\u4e0b\u4e00\u6b65<\/p>\n<\/li>\n<li>\n<p>\u521b\u5efa\u65b0\u865a\u62df\u78c1\u76d8\uff0c\uff08\u4f7f\u7528\u7269\u7406\u78c1\u76d8\u53ef\u80fd\u4f1a\u5f71\u54cd\u5230\u4e3b\u673a\u7cfb\u7edf\u7684\u6b63\u5e38\u4f7f\u7528\uff09\uff0c\u4e0b\u4e00\u6b65<\/p>\n<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u6700\u5927\u78c1\u76d8\u5927\u5c0f\u6839\u636e\u4e2a\u4eba\u9009\u62e9\uff0c\u8fd9\u91cc\u9009\u62e940G\uff0c\u9009\u62e9<strong>\u5c06\u865a\u62df\u78c1\u76d8\u5b58\u50a8\u4e3a\u5355\u4e2a\u6587\u4ef6<\/strong>\uff0c\u4e0b\u4e00\u6b65<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u5b8c\u6210\u521b\u5efa\u865a\u62df\u673a<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<h3 id=\"\u5b89\u88c5-elementary-os\">\u5b89\u88c5 elementary OS<\/h3>\n<ol>\n<li>\n<p>\u5f00\u542f\u6b64\u865a\u62df\u673a<\/p>\n<\/li>\n<li>\n<p>\u8bed\u8a00\u9009\u62e9 <strong>English<\/strong>\uff08\u6216\u8005\u4e2d\u6587\u7b80\u4f53\uff09\uff0c\u70b9\u51fb<strong>Install Elementary<\/strong><\/p>\n<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u9009\u62e9 <strong>Install third-party software<\/strong>\uff0ccontinue<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>Install Type \u9ed8\u8ba4\u9009\u62e9<strong>\u64e6\u9664\u78c1\u76d8\u5b89\u88c5Elementary OS<\/strong>\uff0c\u70b9\u51fb<strong>Install Now<\/strong>\uff0c<strong>Continue<\/strong><\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\n<p>\u9009\u62e9\u57ce\u5e02\uff0c<strong>Contiune<\/strong><\/p>\n<\/li>\n<li>\n<p>\u952e\u76d8\u5e03\u5c40\u9009\u62e9<strong>Chiese<\/strong>\uff0c<strong>Continue<\/strong><\/p>\n<\/li>\n<li>\n<p>\u8bbe\u7f6e\u4e2a\u4eba\u7528\u6237\u540d\u3001\u5bc6\u7801<\/p>\n<\/li>\n<li>\n<p>\u5b89\u88c5\u8fc7\u7a0b\u7b49\u5f855\u5206\u949f\u5de6\u53f3\uff0c\u5b8c\u6210\u540e\u91cd\u542f<\/p>\n<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<h3 id=\"\u5728\u865a\u62df\u673a\u4e2d\u5b89\u88c5-vmtools\">\u5728\u865a\u62df\u673a\u4e2d\u5b89\u88c5 VMTools<\/h3>\n<ol>\n<li>\n<p>\u9009\u62e9 <strong>\u865a\u62df\u673a &gt; \u5b89\u88c5 VMware Tools<\/strong><\/p>\n<\/li>\n<li>\n<p>\u5728\u865a\u62df\u673a\u4e2d\u4f1a\u6302\u8f7d <strong>VMware Tools<\/strong> CD<\/p>\n<\/li>\n<li>\n<p>\u8fdb\u5165\u6302\u8f7d\u7684 <strong>VMware Tools<\/strong>\uff0c\u62f7\u8d1d<strong>VMwareTools<\/strong>\u6587\u4ef6\u5230<strong>Documents<\/strong>\u76ee\u5f55\u4e0b\uff08\u5728CDROM\u4e2d\u65e0\u6cd5\u5199\u5165\uff09<\/p>\n<\/li>\n<li>\n<p>\u8fdb\u5165<strong>Documents<\/strong>\u76ee\u5f55\uff0c\u7528<code>tar<\/code>\u547d\u4ee4\u89e3\u538b<strong>VMwareTools<\/strong>\u6587\u4ef6<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">tar zxf VMwareTools\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u8fdb\u5165\u89e3\u538b\u51fa\u7684<strong>VMwareTools<\/strong>\uff0c\u6267\u884c<strong>vmware-install.pl<\/strong>\u6587\u4ef6<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\"><span class=\"nb\">cd<\/span> VMwareTools\nsudo vmware-install.pl\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u4e00\u8def\u9ed8\u8ba4\u56de\u8f66\uff0c\u5b8c\u6210\u5b89\u88c5<\/p>\n<\/li>\n<li>\n<p>\u8981\u5728\u4e3b\u673a\u548c\u865a\u62df\u673a\u4e4b\u95f4\u62d6\u62fd\u6587\u4ef6\u548c\u590d\u5236\u7c98\u8d34\u6587\u672c\uff0c\u9700\u8981\u6267\u884c<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-shell\" data-lang=\"shell\">\/usr\/bin\/vmware-user\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u6ce8\u9500\uff0c\u91cd\u65b0\u767b\u5f55<\/p>\n<\/li>\n<\/ol>\n<h2 id=\"\u865a\u62df\u673a\u65e0\u6cd5\u8fde\u63a5\u7f51\u7edc\">\u865a\u62df\u673a\u65e0\u6cd5\u8fde\u63a5\u7f51\u7edc<\/h2>\n<ol>\n<li>\u865a\u62df\u673a &gt; \u8bbe\u7f6e &gt; \u9009\u62e9\u6865\u63a5\u6a21\u5f0f<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<ol>\n<li>\u7f16\u8f91 &gt; \u865a\u62df\u7f51\u7edc\u7f16\u8f91\u5668 &gt; \u6865\u63a5\u6a21\u5f0f\u6865\u63a5\u5230\u4f60\u7684\u7269\u7406\u7f51\u5361<\/li>\n<\/ol>\n<!-- raw HTML omitted -->\n<h3 id=\"\u6d4b\u8bd5\u4e3b\u673a\u548c\u865a\u62df\u673a\u4e4b\u95f4\u80fd\u591f\u4e92\u76f8\u8bbf\u95ee\">\u6d4b\u8bd5\u4e3b\u673a\u548c\u865a\u62df\u673a\u4e4b\u95f4\u80fd\u591f\u4e92\u76f8\u8bbf\u95ee<\/h3>\n<ul>\n<li>\u4e3b\u673aping\u865a\u62df\u673aIP<\/li>\n<li>\u865a\u62df\u673a\u8bbf\u95ee\u4e3b\u673a\u5f00\u542f\u7684http\u670d\u52a1\uff08\u53ef\u80fd\u65e0\u6cd5ping\u901a\u4e3b\u673aIP\uff09<\/li>\n<\/ul>\n<hr>\n<p>\u5230\u8fd9\u91cc\uff0celementary OS \u5728 VMware \u4e2d\u5c31\u5b89\u88c5\u5b8c\u6210\u4e86\uff0c\u540e\u9762\u8fd8\u4f1a\u4ecb\u7ecd elementary OS \u7684\u521d\u59cb\u5316\u548c\u4f7f\u7528<\/p>"},{"title":"\u5982\u4f55\u9009\u62e9\u6280\u672f\u535a\u5ba2\u7684\u53d1\u5e03\u65b9\u5f0f","link":"https:\/\/jancat.github.io\/post\/2018\/how-to-select-the-way-to-post-teach-blog\/","pubDate":"Fri, 20 Apr 2018 21:41:23 +0800","guid":"https:\/\/jancat.github.io\/post\/2018\/how-to-select-the-way-to-post-teach-blog\/","description":"<p>\u4e4b\u524d\u4e00\u76f4\u6709\u8bb0\u5f55\u7b14\u8bb0\u7684\u4e60\u60ef\uff0c\u4f46\u90fd\u662f\u4e0d\u516c\u5f00\u53ea\u7ed9\u81ea\u5df1\u770b\u7684\u201c\u7b14\u8bb0\u201d\uff0c\u4e0d\u80fd\u89c1\u4eba\u90a3\u79cd\uff0c\u600e\u4e48\u7b80\u5355\u600e\u4e48\u6765\uff0c\u65b9\u4fbf\u4e0b\u6b21\u5feb\u901f\u7d22\u5f15\uff1b\u8fd9\u6837\u7684\u5185\u5bb9\u80af\u5b9a\u7f3a\u4e4f\u6b63\u5e38\u6587\u7ae0\u8981\u6709\u7684\u5b8c\u6574\u6027\u3001\u53ef\u8bfb\u6027\u3001\u903b\u8f91\u8fde\u8d2f\u6027\u3002\u3002\u3002<\/p>\n<p>\u4e3a\u4e86\u953b\u70bc\u81ea\u5df1\u7684\u6587\u5b57\u8868\u8fbe\u80fd\u529b\uff0c\u548c\u672c\u7740\u77e5\u8bc6\u5206\u4eab\u7684\u7cbe\u795e\uff0c\u987a\u5e26\u7cfb\u7edf\u6574\u7406\u4e0b\u66fe\u7ecf\u7684\u4e2a\u4eba\u7b14\u8bb0\uff0c\u4e8e\u662f\u5f00\u59cb\u5199\u516c\u5f00\u7684\u535a\u5ba2\u6587\u7ae0\uff0c\u5728\u641c\u7d22\u5f15\u64ce\u4e2d\u7559\u4e0b\u81ea\u5df1\u7684\u5370\u8bb0\u3002<\/p>\n<h4 id=\"\u6587\u7ae0\u53d1\u5e03\u7f51\u7ad9\u7684\u9009\u62e9\">\u6587\u7ae0\u53d1\u5e03\u7f51\u7ad9\u7684\u9009\u62e9<\/h4>\n<p>\u6280\u672f\u6587\u7ae0\u5982\u679c\u8981\u53d1\u5e03\u5728\u516c\u5171\u7684\u7f51\u7ad9\u4e0a\uff0c\u73b0\u5728\u4e00\u822c\u6709\u51e0\u79cd\u9009\u62e9\uff1a<\/p>\n<ul>\n<li>\n<p><strong>\u6398\u91d1<\/strong><\/p>\n<p>\u6398\u91d1\u662f\u4e00\u4e2a\u4f18\u79c0\u7684\u5f00\u53d1\u8005\u793e\u533a\uff0c\u6280\u672f\u6c1b\u56f4\u6d53\u539a\uff0c\u6587\u7ae0\u8d28\u91cf\u8fd8\u53ef\u4ee5\uff0c\u5c24\u5176\u524d\u7aef\u3002<\/p>\n<\/li>\n<li>\n<p><strong>\u7b80\u4e66<\/strong><\/p>\n<p>\u6bd4\u8f83\u53d7\u6b22\u8fce\u7684Markdown\u6587\u7ae0\u521b\u4f5c\u793e\u533a\uff0c\u5404\u79cd\u7c7b\u578b\u7684\u6587\u7ae0\u90fd\u6709\uff0c\u4f46\u5c31\u662f\u56e0\u4e3a\u592a\u6cdb\u4e86\uff0c\u6280\u672f\u6c1b\u56f4\u4e0d\u591f\uff0c\u4e13\u4e1a\u6027\u4e0d\u5f3a\u3002\u4f46\u5bf9\u4e8e\u666e\u901a\u7684\u4e0d\u7231\u6298\u817e\u7684\u4f5c\u8005\u6765\u8bf4\u5df2\u7ecf\u8db3\u591f\u4e86\uff0c\u53ef\u4ee5\u66f4\u52a0\u4e13\u6ce8\u5728\u6587\u7ae0\u521b\u4f5c\u4e0a\u3002<\/p>\n<\/li>\n<li>\n<p><strong>segmentfault<\/strong><\/p>\n<p>segmentfault \u4e13\u680f\u4e5f\u662f\u53d1\u5e03\u6280\u672f\u6587\u7ae0\u6bd4\u8f83\u597d\u7684\u9009\u62e9\uff0c\u7f51\u7ad9\u4f53\u9a8c\u4e5f\u5f88\u4e0d\u9519\uff0c\u76f8\u4fe1\u4f1a\u8d8a\u6765\u8d8a\u6d41\u884c\u3002<\/p>\n<\/li>\n<li>\n<p><strong>\u77e5\u4e4e<\/strong><\/p>\n<blockquote>\n<p>\u7a0b\u5e8f\u5458\u5c0f\u9690\u9690\u4e8e\u91ce\uff0c\u4e2d\u9690\u9690\u4e8e\u697c\uff0c\u5927\u9690\u9690\u77e5\u4e4e<\/p>\n<\/blockquote>\n<p>\u5f88\u591a\u7a0b\u5e8f\u5458\u7ecf\u5e38\u51fa\u6ca1\u4e8e\u77e5\u4e4e\uff0c\u6280\u672f\u6587\u7ae0\u4e5f\u5f88\u81ea\u7136\u5730\u4f1a\u53d1\u5728\u4e0a\u9762\u3002\u4f46\u4e5f\u662f\u8ddf\u7b80\u4e66\u4e00\u6837\u7684\u60c5\u51b5\uff0c\u5939\u6742\u5728\u8fd9\u4e48\u591a\u975e\u6280\u672f\u6587\u7ae0\/\u95ee\u7b54\u4e2d\uff0c\u603b\u662f\u611f\u89c9\u4e0d\u591f\u4e13\u4e1a\uff0c\u6bd4\u7b80\u4e66\u66f4\u751a\u3002<\/p>\n<\/li>\n<\/ul>\n<p>\u5982\u679c\u4e0a\u9762\u51e0\u79cd\u65b9\u5f0f\u90fd\u4e0d\u80fd\u6ee1\u8db3\u4f60\uff0c\u90a3\u6216\u8bb8\u4f60\u662f\u4e2a\u6bd4\u8f83\u559c\u6b22\u6298\u817e\u7684\u4eba\uff0c\u60f3\u8981\u4e0e\u4f17\u4e0d\u540c\uff0c\u5c1d\u8bd5\u81ea\u5df1\u5efa\u535a\u5ba2\u7f51\u7ad9\uff0c\u5efa\u7acb\u72ec\u7279\u7684\u4e2a\u4eba\u6807\u8bc6\u3002<\/p>\n<h4 id=\"\u4ece\u96f6\u5199\u8d77-or-\u4f7f\u7528\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668\">\u4ece\u96f6\u5199\u8d77 or \u4f7f\u7528\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668\uff1f<\/h4>\n<p>\u81ea\u5efa\u535a\u5ba2\u7f51\u7ad9\u4e5f\u662f\u4e00\u6761\u5766\u5766\u5927\u9053\uff0c\u5f88\u591a\u7a0b\u5e8f\u5458\u90fd\u559c\u6b22\u6709\u81ea\u5df1\u4e13\u5c5e\u7684\u7f51\u7ad9\uff0c\u58f0\u660e\u81ea\u5df1\u7684\u72ec\u7279\u6027\u3002\u4e2a\u4eba\u7f51\u7ad9\u51e0\u4e4e\u6210\u4e86Geek\u7684\u6807\u914d\uff0c\u5982\u679c\u6ca1\u6709\u53cd\u800c\u4f1a\u6709\u70b9\u5947\u602a\u3002<\/p>\n<p>\u4e2a\u4eba\u535a\u5ba2\u867d\u7136\u4e0d\u662f\u590d\u6742\u7684\u7f51\u7ad9\uff0c\u4f46\u662f\u8981\u81ea\u5df1\u4ece\u96f6\u5199\u51fa\u6765\u8fbe\u5230\u80fd\u6ee1\u8db3\u6b63\u5e38\u4f7f\u7528\u7684\u7a0b\u5ea6\uff0c\u8fd8\u662f\u8981\u82b1\u5927\u91cf\u65f6\u95f4\u7cbe\u529b\u5728\u4e0a\u9762\u7684\u3002\u867d\u7136\u8fd9\u6837\u80fd\u51f8\u663e\u81ea\u5df1\u7684\u80fd\u529b\uff0c\u4e2a\u6027\u5316\u7a0b\u5ea6\u9ad8\uff0c\u4f46\u5982\u679c\u4e0d\u662f\u6267\u7740\u4e8e\u201c<strong>DIY<\/strong>\u201d\uff0c\u8fd9\u91cc\u8fd8\u662f\u4e0d\u63a8\u8350\u8fd9\u79cd\u65b9\u5f0f\u7684\u3002<\/p>\n<p>\u90a3\u6700\u540e\u5c31\u5269\u4e0b <strong>\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668(SSG, Static Site Generator)<\/strong> \u8fd9\u4e2a\u9009\u62e9\u4e86\uff0c\u5173\u4e8e <strong>SSG<\/strong> \uff0c\u53ef\u4ee5\u9605\u8bfb\u8fd9\u4e2a\u535a\u5ba2\u7684\u524d\u534a\u90e8\u5206 <a href=\"https:\/\/www.jianshu.com\/p\/c50dab7a98ef\">\u5229\u7528\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668\u5236\u4f5c\u9759\u6001\u535a\u5ba2\u7f51\u7ad9<\/a>\u3002<\/p>\n<p>\u7b80\u5355\u6765\u8bf4\uff0c<strong>SSG<\/strong> \u5c31\u662f\u5e2e\u6211\u4eec\u81ea\u52a8\u751f\u6210\u9759\u6001\u7f51\u7ad9\u7684\u5de5\u5177\uff0c\u5f88\u591a\u5f00\u6e90\u7684\u7f51\u7ad9\u4e3b\u9898\u53ef\u4ee5\u9009\u62e9\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5df1\u5236\u4f5c\u4e3b\u9898\u81ea\u7528\u548c\u5171\u4eab\u3002\u4e00\u822c\u53ea\u8981\u6539\u4e0b\u914d\u7f6e\u6587\u4ef6\u548c\u521b\u5efamarkdown\u6587\u7ae0\u5c31\u80fd\u90e8\u7f72\u4e86\u3002<\/p>\n<h4 id=\"\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668\u7684\u9009\u62e9\">\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668\u7684\u9009\u62e9<\/h4>\n<p>\u9759\u6001\u7f51\u7ad9\u751f\u6210\u5668 \u73b0\u5728\u6709\u4e0a\u767e\u4e2a\uff0c\u539f\u7406\u548c\u4f7f\u7528\u65b9\u5f0f\u90fd\u5927\u540c\u5c0f\u5f02\uff0c\u4f46\u5728\u4e0d\u4e86\u89e3\u7684\u60c5\u51b5\u4e0b\u9009\u62e9\u51fa\u6700\u5408\u9002\u81ea\u5df1\u7684\u8fd8\u662f\u6bd4\u8f83\u7ea0\u7ed3\u7684\u3002\u5e78\u597d\u6709\u4e2a\u4e13\u95e8\u7edf\u8ba1 <strong>SSG<\/strong> \u7684\u7f51\u7ad9 <a href=\"https:\/\/www.staticgen.com\/\">Staitc Gen<\/a>\uff0c\u91cc\u9762\u5c55\u793a\u4e86\u51e0\u4e4e\u6240\u6709\u5f00\u6e90\u7684 <strong>SSG<\/strong>\uff0c\u6839\u636eGithub Project\u7684\u6570\u636e\uff08\u9ed8\u8ba4\u662fStars\u6570\uff09\u6765\u8fdb\u884c\u6392\u5217\u3002<\/p>\n<p>\u8fd9\u91cc\u5c31\u4ece\u4e3b\u8981\u7684\u4e09\u4e2a <strong>SSG<\/strong> \u6765\u9009\u62e9\uff1a<strong>Jekyll<\/strong>\u3001<strong>Hugo<\/strong>\u3001<strong>Hexo<\/strong><\/p>\n<h4 id=\"jekyll\">Jekyll<\/h4>\n<p><a href=\"https:\/\/jekyllrb.com\/\">Jekyll<\/a> \u662f\u6bd4\u8f83\u65e9\u671f\u7684\u9879\u76ee\u4e86\uff0c\u4ece2008\u5e74\u5f00\u59cb\uff0c\u76ee\u524dGithub Stars\u6570\u91cf\u6392\u884c\u7b2c\u4e00\uff1b\u4f7f\u7528 <strong>Ruby<\/strong> \u8bed\u8a00\u5b9e\u73b0\uff0c\u662f <strong>Github Pages<\/strong> \u63a8\u8350\u7684 SSG\u3002<\/p>\n<p>\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u4f18\u5148\u9009\u62e9\u6700\u6d41\u884c\u7684\u662f\u6ca1\u9519\u7684\uff0c\u6240\u4ee5\u9996\u5148\u62ff <code>Jekyll<\/code> \u5728 <strong>Win10<\/strong> \u4e0a\u8bd5\u8bd5\u6c34\u3002<\/p>\n<p>\u6309\u7167\u5b98\u7f51\u7684\u5b89\u88c5\u6b65\u9aa4\u8d70\uff0c\u5728 <code>Win10<\/code> \u4e0a\u51c6\u5907\u73af\u5883\u8fd8\u662f\u6bd4\u8f83<strong>\u8270\u96be<\/strong>\u7684\uff0c\u5149 <strong>Ruby<\/strong> \u73af\u5883\u7684\u5b89\u88c5\u90fd\u5f88<strong>\u6298\u817e<\/strong>\uff0c\u5373\u4f7f\u6309\u7167\u5b98\u7f51\u63a8\u8350\u7684\u65b9\u5f0f\u4f7f\u7528<strong>WSL<\/strong>(Window Subsystem Linux)\uff0c<strong>\u5728Win10\u4e0a\u5b89\u88c5Ubuntu<\/strong> \u7ec8\u7aef\u73af\u5883\uff0c\u6700\u540e\u8fd8\u662f\u51fa\u73b0\u5f88\u591a\u95ee\u9898\u6ca1\u89e3\u51b3\uff0c\u8fd8\u6ca1\u8d70\u5230 <strong>Jekyll<\/strong> \u90a3\u4e00\u6b65\u5c31\u88ab\u5751\u5728\u6d1e\u91cc\u722c\u4e0d\u51fa\u6765\uff0c\u9042\u653e\u5f03\u3002<\/p>\n<p><strong>\u4e0d\u5efa\u8bae\u5728Win10\u7cfb\u7edf\u4e0a\u5b89\u88c5Jekyll<\/strong>\u3002<\/p>\n<p>\u5728<strong>Mac<\/strong>\u4e0a\u5b89\u88c5\u5e94\u8be5\u6bd4\u8f83\u5bb9\u6613\uff0c\u4f46\u8fd9\u91cc\u53ea\u8ba8\u8bba<strong>Windows<\/strong>\u7cfb\u7edf\u73af\u5883\uff0cMac\u515a\u53ef\u4ee5\u5c1d\u8bd5\u4e00\u4e0b\u3002<\/p>\n<h4 id=\"hexo\">Hexo<\/h4>\n<p><a href=\"https:\/\/hexo.io\/\">Hexo<\/a> \u662f2012\u5e74\u7684\u9879\u76ee\uff0c\u53d1\u5c55\u5230\u73b0\u5728\uff0c\u4e5f\u662f\u76ee\u524d\u4f7f\u7528\u7684\u6bd4\u8f83\u591a\u7684SSG\u3002Github Stars\u6570\u91cf\u6392\u7b2c\u56db\uff0c\u4f7f\u7528 <strong>Node.js<\/strong> \u5b9e\u73b0\u3002<\/p>\n<p>\u5982\u679c\u4e0d\u662f\u540e\u9762\u65b0\u5d1b\u8d77\u7684 <strong>Hugo<\/strong>\uff0c\u6216\u8bb8\u5c31\u88ab\u6211\u9009\u4e2d\u4e86\uff0c\u53ef\u60dc\u6ca1\u6709\u5982\u679c\u3002<\/p>\n<h4 id=\"hugo\">Hugo<\/h4>\n<blockquote>\n<p>\u672c\u6587\u538b\u8f74\u7ec8\u4e8e\u51fa\u573a\u4e86\ud83c\udf89<\/p>\n<\/blockquote>\n<p><a href=\"http:\/\/gohugo.io\/\">Hugo<\/a> \u4f7f\u7528 <strong>Go<\/strong> \u8bed\u8a00\u5b9e\u73b0\uff0c\u76ee\u524dGithub Stars\u6570\u91cf\u6392\u7b2c\u4e8c\uff0c\u4ec5\u6b21\u4e8e\u8001\u724c Jekyll\u3002\u5d1b\u8d77\u4e8e2017\u5e74\uff0c\u57282018\u5e74\u4f5c\u4e3a\u65b0\u5174SSG\u8fc5\u901f\u6d41\u884c\u8d77\u6765\uff0c\u672c\u7ad9\u4e5f\u662f\u4f7f\u7528 Hugo \u5efa\u7ad9\u3002\u5b98\u7f51\u4e0a\u53f7\u79f0\u201c<strong>\u4e16\u754c\u4e0a\u5efa\u7ad9\u6700\u5feb\u7684\u6846\u67b6<\/strong>\u201d\uff08\u5b98\u7f51\u4f60\u76ae\u8fd9\u4e00\u4e0b\u5f00\u5fc3\u5417\uff1f\uff09<\/p>\n<p>hugo.io \u57df\u540d\u88ab\u62a2\u6ce8\u4e86\uff0c\u5b98\u7f51\u7528 gohugo.io \u867d\u662f\u65e0\u5948\u4e4b\u4e3e\uff0c\u4f46\u4e5f\u633a\u673a\u667a\u3002<\/p>\n<p>Win10 \u8f7b\u677e\u5b89\u88c5 Hugo \u27a1 <code>choco install hugo<\/code><\/p>\n<p>Hugo \u6a21\u677f\u8bed\u6cd5\u4e0d\u592a\u9002\u5e94\uff0c\u5982\u679c\u9700\u8981\u81ea\u5df1\u521b\u5efa\u4e3b\u9898\u6216\u8005\u81ea\u5b9a\u4e49\u5df2\u6709\u7684\u4e3b\u9898\uff0c\u8fd8\u662f\u5148\u8981\u5728\u5b98\u7f51\u4e86\u89e3\u4e00\u5806\u6982\u5ff5\u7684\u3002<\/p>\n<p>\u5e0c\u671b\u6709\u4e00\u5929\u80fd\u591f\u51fa\u81ea\u5df1\u7684\u4e3b\u9898\ud83d\ude43<\/p>\n<h4 id=\"\u6700\u540e\">\u6700\u540e<\/h4>\n<p>\u4ee5\u4e0a\u53ea\u662f\u6211\u4e2a\u4eba\u7684\u7ecf\u9a8c\u89c1\u89e3\uff0c\u4ec5\u4f9b\u53c2\u8003\uff0c\u600e\u6837\u9009\u62e9\u8fd8\u662f\u8981\u9760<strong>\u773c\u7f18<\/strong>\u548c<strong>\u773c\u529b<\/strong><\/p>\n<p>\uff08\u5982\u679c\u8fd8\u662f\u7ea0\u7ed3\uff0c\u90a3\u5c31 <strong>Hugo<\/strong> \u5427\uff09<\/p>"},{"title":"\u5173\u4e8e","link":"https:\/\/jancat.github.io\/about\/","pubDate":"Fri, 20 Apr 2018 09:10:24 +0000","guid":"https:\/\/jancat.github.io\/about\/","description":"<p><img src=\"https:\/\/jancat.github.io\/images\/post\/about\/about-background.jpg\" alt=\"background\"><\/p>\n<p>\u6e38\u8d70\u4e8e\u6587\u827a\u8fb9\u7f18\uff0c\u5fc3\u4e2d\u5e38\u4f4f\u7740\u6301\u5251\u7684\u5c11\u5e74<\/p>\n<p>\u5411\u5f80\u4e8c\u6b21\u5143\uff0c\u6b63\u56e0\u65e0\u6cd5\u4f01\u53ca<\/p>\n<p>\u559c\u6b22Coding\u5e26\u6765\u7684\u6210\u5c31\u611f<\/p>\n"},{"title":"\u4f7f\u7528Node\u548cTypescript\u722c\u53d6\u82b1\u74e3\u7f51\u56fe\u7247","link":"https:\/\/jancat.github.io\/post\/2018\/huaban-crawler-with-node-and-typescript\/","pubDate":"Thu, 19 Apr 2018 04:03:44 +0000","guid":"https:\/\/jancat.github.io\/post\/2018\/huaban-crawler-with-node-and-typescript\/","description":"<p><img src=\"https:\/\/jancat.github.io\/images\/post\/huaban-crawler-with-node-and-typescript\/huban-logo.jpg\" alt=\"huban-logo\"><\/p>\n<!-- raw HTML omitted -->\n<!-- raw HTML omitted -->\n<ul>\n<li><a href=\"#%E5%89%8D%E8%A8%80\">\u524d\u8a00<\/a>\n<ul>\n<li><a href=\"#%E6%8A%80%E6%9C%AF%E9%80%89%E5%9E%8B\">\u6280\u672f\u9009\u578b<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#%E8%8A%B1%E7%93%A3%E7%BD%91%E6%8A%80%E6%9C%AF%E5%88%86%E6%9E%90\">\u82b1\u74e3\u7f51\u6280\u672f\u5206\u6790<\/a>\n<ul>\n<li><a href=\"#%E7%94%BB%E6%9D%BF%E8%B5%84%E6%BA%90\">\u753b\u677f\u8d44\u6e90<\/a><\/li>\n<li><a href=\"#board-data\">Board Data<\/a><\/li>\n<li><a href=\"#%E5%9B%BE%E7%89%87%E6%87%92%E5%8A%A0%E8%BD%BD\">\u56fe\u7247\u61d2\u52a0\u8f7d<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#node-%E7%88%AC%E8%99%AB%E5%AE%9E%E7%8E%B0\">Node \u722c\u866b\u5b9e\u73b0<\/a>\n<ul>\n<li><a href=\"#%E8%BE%93%E5%85%A5%E7%94%BB%E6%9D%BFid%E4%B8%8B%E8%BD%BD%E8%AF%A5%E7%94%BB%E6%9D%BF%E7%9A%84%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87\">\u8f93\u5165\u753b\u677fID\u4e0b\u8f7d\u8be5\u753b\u677f\u7684\u6240\u6709\u56fe\u7247<\/a><\/li>\n<li><a href=\"#%E8%BE%93%E5%85%A5%E7%94%A8%E6%88%B7id%E4%B8%8B%E8%BD%BD%E8%AF%A5%E7%94%A8%E6%88%B7%E6%89%80%E6%9C%89%E8%87%AA%E5%BB%BA%E7%94%BB%E6%9D%BF%E7%9A%84%E5%9B%BE%E7%89%87%E4%B8%8D%E5%8C%85%E6%8B%AC%E6%94%B6%E8%97%8F%E7%9A%84%E7%94%BB%E6%9D%BF\">\u8f93\u5165\u7528\u6237ID\u4e0b\u8f7d\u8be5\u7528\u6237\u6240\u6709\u81ea\u5efa\u753b\u677f\u7684\u56fe\u7247\uff08\u4e0d\u5305\u62ec\u6536\u85cf\u7684\u753b\u677f\uff09<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#%E6%80%BB%E7%BB%93\">\u603b\u7ed3<\/a><\/li>\n<li><a href=\"#github-project\">Github Project<\/a><\/li>\n<\/ul>\n<!-- raw HTML omitted -->\n<h2 id=\"\u524d\u8a00\">\u524d\u8a00<\/h2>\n<p><a href=\"https:\/\/huaban.com\">\u82b1\u74e3\u7f51<\/a> \u6700\u521d\u662f\u6a21\u4eff\u56fd\u5916\u7684 <a href=\"https:\/\/www.pinterest.com\/\">Pinterest<\/a> \u5f00\u59cb\u505a\u8d77\u6765\u7684\u56fe\u7247\u91c7\u96c6\u5206\u4eab\u7f51\u7ad9\uff0c\u56fd\u5185\u7c7b\u4f3c\u7684\u7f51\u7ad9\u6709<a href=\"https:\/\/www.duitang.com\/\">\u5806\u7cd6<\/a>\u3002\u5728\u521d\u671f\u7684\u7528\u6237\u79ef\u7d2f\u9636\u6bb5\u8fc7\u540e\uff0c\u82b1\u74e3\u7f51\u8fd1\u51e0\u5e74\u5f00\u59cb\u63a2\u7d22\u5176\u5546\u4e1a\u6a21\u5f0f\uff0c\u4ee5\u201c\u56fe\u201d\u4e3a\u4e2d\u5fc3\u5411\u76f8\u5173\u9886\u57df\u5ef6\u4f38\uff08\u6444\u5f71\u3001\u8bbe\u8ba1\u3001Live\u3001\u7535\u5546\u5bfc\u8d2d\u7b49\uff09\uff0c\u4e0d\u8fc7\u4e0d\u7ba1\u600e\u4e48\u53d1\u5c55\uff0c\u7528\u6237\u4f53\u9a8c\u8fd8\u662f\u8981\u653e\u5728\u9996\u4f4d\u7684\uff0c\u4e0d\u5fd8\u521d\u8877\u3002<\/p>\n<p>\u4f5c\u4e3a\u56fd\u5185\u4f18\u79c0\u7684\u56fe\u7247\u7f51\u7ad9,\u5176\u6d41\u7545\u7684\u7011\u5e03\u6d41\u56fe\u7247\u5c55\u793a\u3001\u7b80\u5355\u6613\u7528\u7684\u56fe\u7247\u91c7\u96c6\u5206\u7c7b\u65b9\u5f0f\u3001\u5f3a\u5927\u7684\u56fe\u7247\u91c7\u96c6\u63d2\u4ef6\uff0c\u8ba9\u6211\u8fd9\u4e2a\u56fe\u63a7\u575a\u6301\u5728\u8fd9\u91cc\u6df1\u8015\u591a\u5e74\uff0c\u91c7\u96c6\u4e86\u51e0\u4e07\u5f20\u56fe\u7247\uff0c\u9a97\u7c89\u51e0\u5343\u4e2a\uff08\u6b22\u8fce\u5173\u6ce8 <a href=\"http:\/\/huaban.com\/junlin\/\">http:\/\/huaban.com\/junlin\/<\/a> \uff09\u3002<\/p>\n<p>\u7136\u800c\u5bf9\u4e8e<strong>\u56fe\u63a7+\u6536\u85cf\u63a7<\/strong>\u6765\u8bf4\uff0c\u82b1\u74e3\u7f51\u4e5f\u53ea\u662f<strong>\u4e2a\u4eba\u56fe\u5e93\u5927\u8ba1<\/strong>\u4e2d\u7684\u5176\u4e2d\u4e00\u73af\uff0c\u6bd5\u7adf\u8fd8\u662f\u6709\u5f88\u591a<del>\u79c1\u56fe<\/del>\u4e0d\u5b9c\u5149\u660e\u6b63\u5927\u653e\u51fa\u6765\u7684\uff0c\u82b1\u74e3\u7f51\u4e5f\u6709\u8fdd\u89c4\u56fe\u7247\u68c0\u6d4b\u673a\u5236\uff0c\u6240\u4ee5\u9700\u8981\u6c47\u603b\u82b1\u74e3\u7f51\u91c7\u96c6\u7684\u56fe\u7247\u5230\u4e2a\u4eba\u5b58\u50a8\u5e93\u4e2d\uff08\u7f51\u76d8or\u786c\u76d8\uff09\uff1b\u6b64\u4e3a<!-- raw HTML omitted -->\u7eaf\u7eaf\u7684<!-- raw HTML omitted -->\u52a8\u673a\uff0c\u4e5f\u662f\u672c\u6587\u51fa\u73b0\u7684\u539f\u56e0\u3002<\/p>\n<h3 id=\"\u6280\u672f\u9009\u578b\">\u6280\u672f\u9009\u578b<\/h3>\n<p>\u8fd9\u4e48\u591a\u56fe\u7247\u624b\u5de5\u4e00\u4e2a\u4e2a\u4e0b\u8f7d\u80af\u5b9a\u662f\u4e0d\u73b0\u5b9e\u7684\uff0c\u82b1\u74e3\u7f51\u4e5f\u6ca1\u6709\u63d0\u4f9b\u6279\u91cf\u4e0b\u8f7d\u753b\u677f\u7684\u529f\u80fd\uff08\u8981\u662f\u6709\u5c31\u7701\u5fc3\u4e86\uff0c\u53ef\u80fd\u662f\u8003\u8651\u5230\u8fd9\u529f\u80fd\u5f00\u653e\u540e\u4f1a\u5f71\u54cd\u7f51\u7ad9\u8fd0\u8425\uff09\uff0c\u8fd9\u6837\u5c31\u50ac\u751f\u4e86\u5f88\u591a\u6279\u91cf\u4e0b\u8f7d\u5de5\u5177\u3001\u811a\u672c\uff08<a href=\"https:\/\/www.douban.com\/group\/473118\/\">\u8c46\u76aeDouP\u76f8\u518c\u4e0b\u8f7d\u5668\u8c46\u74e3\u5c0f\u7ec4<\/a>\u3001Github \u722c\u866b\u9879\u76ee\uff09\uff0c\u57fa\u672c\u90fd\u80fd\u5f88\u65b9\u4fbf\u7684\u4e0b\u8f7d\u3002<\/p>\n<p>\u672c\u7740\u4e00\u9897\u4e0d\u5b89\u5206\u559c\u6b22\u6298\u817e\u7684\u5fc3\uff0c\u4e5f\u662f\u51fa\u4e8e\u6280\u672f\u5b66\u4e60\u76ee\u7684\uff0c\u6253\u7b97\u81ea\u5df1\u5b9e\u73b0\u4e00\u4e2a\u6279\u91cf\u4e0b\u8f7d\u7684\u722c\u866b\u811a\u672c\u3002\u867d\u7136\u722c\u866b\u9996\u9009Python\uff0c\u4f46\uff0c\u4f5c\u4e3a\u76f8\u4fe1\u7740 <strong>Atwood\u5b9a\u5f8b<\/strong> \u7684\u524d\u7aefer\uff0c<\/p>\n<blockquote>\n<p>any application that can be written in JavaScript, will eventually be written in JavaScript.\n\uff08\u4efb\u4f55\u80fd\u591f\u7528JavaScript\u5b9e\u73b0\u7684\u5e94\u7528\uff0c\u6700\u7ec8\u90fd\u5fc5\u5c06\u7531JavaScript\u5b9e\u73b0\u3002\uff09\n&ndash; Jeff Atwood<\/p>\n<\/blockquote>\n<p>\u5f88\u81ea\u7136\u7684\u9009\u62e9\u4e86 <strong>Node.js<\/strong> \uff0c\u518d\u52a0\u4e0a\u8d8a\u6765\u8d8a\u6765\u6d41\u884c\u7684 <strong>TypeScript<\/strong>\uff0c\u5982\u864e\u6dfb\u7ffc\uff0cPerfect\uff01<\/p>\n<h2 id=\"\u82b1\u74e3\u7f51\u6280\u672f\u5206\u6790\">\u82b1\u74e3\u7f51\u6280\u672f\u5206\u6790<\/h2>\n<p>\u9996\u5148\u6253\u5f00\u82b1\u74e3\u7f51\u4efb\u610f\u4e00\u4e2a<strong>\u753b\u677f<\/strong>\uff0c\u5728 Chrome DevTools - Network \u4e0b\u89c2\u5bdf\u5b83\u548c\u670d\u52a1\u5668\u4e4b\u524d\u7684\u4ea4\u4e92\u3002<\/p>\n<h3 id=\"\u753b\u677f\u8d44\u6e90\">\u753b\u677f\u8d44\u6e90<\/h3>\n<p>\u5237\u65b0\u540e\u53d1\u73b0\u6709\u5f88\u591a\u7f51\u7edc\u8bf7\u6c42\uff0c\u6ce8\u610f\u5230\u6700\u5f00\u59cb\u6709\u4e2a\u5e26\u6709<strong>\u753b\u677fID<\/strong>\u7684 Request <a href=\"http:\/\/huaban.com\/boards\/17473820\/\">http:\/\/huaban.com\/boards\/17473820\/<\/a> \uff0c\u5e94\u8be5\u5c31\u662f\u5b83\u4e86\uff0c\u670d\u52a1\u5668\u54cd\u5e94\u7684\u662f\u4e00\u4e2a HTML Document\u3002<\/p>\n<p><img src=\"https:\/\/jancat.github.io\/images\/post\/huaban-crawler-with-node-and-typescript\/board-request.png\" alt=\"board-request\"><\/p>\n<h3 id=\"board-data\">Board Data<\/h3>\n<p>\u5728\u8fd9\u4e2a HTML Document \u4e2d\u53d1\u73b0\u6709\u4e2a <code>&lt;script&gt;<\/code> \u4e2d\u5e26\u6709\u5927\u91cf\u7684 <strong>board<\/strong> \u6570\u636e\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><span class=\"lnt\">36\n<\/span><span class=\"lnt\">37\n<\/span><span class=\"lnt\">38\n<\/span><span class=\"lnt\">39\n<\/span><span class=\"lnt\">40\n<\/span><span class=\"lnt\">41\n<\/span><span class=\"lnt\">42\n<\/span><span class=\"lnt\">43\n<\/span><span class=\"lnt\">44\n<\/span><span class=\"lnt\">45\n<\/span><span class=\"lnt\">46\n<\/span><span class=\"lnt\">47\n<\/span><span class=\"lnt\">48\n<\/span><span class=\"lnt\">49\n<\/span><span class=\"lnt\">50\n<\/span><span class=\"lnt\">51\n<\/span><span class=\"lnt\">52\n<\/span><span class=\"lnt\">53\n<\/span><span class=\"lnt\">54\n<\/span><span class=\"lnt\">55\n<\/span><span class=\"lnt\">56\n<\/span><span class=\"lnt\">57\n<\/span><span class=\"lnt\">58\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">app<\/span><span class=\"p\">.<\/span><span class=\"nx\">page<\/span><span class=\"p\">[<\/span><span class=\"s1\">&#39;board&#39;<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">board_id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">17473820<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">user_id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">14191742<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">title<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;\u25c8 \u4e8c\u6b21\u5143 \u5c11\u5973 \u25c8&#39;<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">description<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;\u4e09\u6b21\u5143\u4e4b\u5916\u7684\u4e00\u7247\u51c0\u571f\uff0c\u6ee1\u6ee1\u7684\u6cbb\u6108~&#39;<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">category_id<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;anime&#39;<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">seq<\/span><span class=\"o\">:<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">pin_count<\/span><span class=\"o\">:<\/span> <span class=\"mi\">12627<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">follow_count<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1004<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">like_count<\/span><span class=\"o\">:<\/span> <span class=\"mi\">37<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">created_at<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1410342416<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">updated_at<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1523766920<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">deleting<\/span><span class=\"o\">:<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">is_private<\/span><span class=\"o\">:<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">extra<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">cover<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">pin_id<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;407033830&#39;<\/span> <span class=\"p\">}<\/span> <span class=\"p\">},<\/span>\n  <span class=\"nx\">user<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span> <span class=\"p\">...<\/span> <span class=\"p\">},<\/span>\n  <span class=\"nx\">category_name<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;\u52a8\u6f2b&#39;<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">following<\/span><span class=\"o\">:<\/span> <span class=\"kc\">false<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">liked<\/span><span class=\"o\">:<\/span> <span class=\"kc\">false<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">pins<\/span><span class=\"o\">:<\/span> <span class=\"p\">[<\/span>\n    <span class=\"p\">{<\/span>\n      <span class=\"nx\">pin_id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1595477246<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">user_id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">14191742<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">board_id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">17473820<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">file_id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">183940093<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">file<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">183940093<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">farm<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;farm1&#39;<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">bucket<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;hbimg&#39;<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">key<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;95b6f7594128756a5fb415188cb5761c4139cebbf359b-R9Dvyn&#39;<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">type<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;image\/jpeg&#39;<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">width<\/span><span class=\"o\">:<\/span> <span class=\"mi\">752<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">height<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1062<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">frames<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">colors<\/span><span class=\"o\">:<\/span> <span class=\"p\">[{<\/span> <span class=\"nx\">color<\/span><span class=\"o\">:<\/span> <span class=\"mi\">5934<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ratio<\/span><span class=\"o\">:<\/span> <span class=\"mf\">0.09<\/span> <span class=\"p\">}],<\/span>\n        <span class=\"nx\">theme<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;00172e&#39;<\/span><span class=\"p\">,<\/span>\n      <span class=\"p\">},<\/span>\n      <span class=\"nx\">media_type<\/span><span class=\"o\">:<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">source<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;pixiv.net&#39;<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">link<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;https:\/\/www.pixiv.net\/member_illust.php?mode=medium&amp;illust_id=67752097&#39;<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">raw_text<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;\u594f\u3055\u3093&#39;<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">text_meta<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">tags<\/span><span class=\"o\">:<\/span> <span class=\"p\">[]<\/span> <span class=\"p\">},<\/span>\n      <span class=\"nx\">via<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1587727234<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">via_user_id<\/span><span class=\"o\">:<\/span> <span class=\"mi\">8451317<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">original<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1568136527<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">created_at<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1523444564<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">like_count<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">comment_count<\/span><span class=\"o\">:<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">repin_count<\/span><span class=\"o\">:<\/span> <span class=\"mi\">3<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">is_private<\/span><span class=\"o\">:<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">extra<\/span><span class=\"o\">:<\/span> <span class=\"kc\">null<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">orig_source<\/span><span class=\"o\">:<\/span> <span class=\"kc\">null<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">tags<\/span><span class=\"o\">:<\/span> <span class=\"p\">[],<\/span>\n    <span class=\"p\">},<\/span>\n    <span class=\"p\">{<\/span> <span class=\"p\">...<\/span> <span class=\"p\">},<\/span>\n    <span class=\"p\">...<\/span>\n  <span class=\"p\">]<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><p>\u5176\u4e2d <code>app.page.board.pins<\/code> \u662f\u4e00\u4e2a\u5bf9\u8c61\u6570\u7ec4\uff0c\u91cc\u9762\u6bcf\u4e2a\u5bf9\u8c61\u5bf9\u5e94\u7740\u753b\u677f\u4e2d\u5176\u4e2d\u4e00\u5f20\u56fe\u7247\u7684\u4fe1\u606f\uff0c<code>pin<\/code> \u4ee3\u8868\u4e00\u5f20\u56fe\u7247\u7684\u4fe1\u606f\u3002<\/p>\n<p>\u5728\u7f51\u9875\u4e2d\u68c0\u67e5\u7b2c\u4e00\u5f20\u56fe\u7247\u7684\u6e90 <code>&lt;img src=&quot;\/\/img.hb.aicdn.com\/95b6f7594128756a5fb415188cb5761c4139cebbf359b-R9Dvyn_fw236&quot;&gt;<\/code>\uff0c\u53ef\u4ee5\u53d1\u73b0\u82b1\u74e3\u7f51\u56fe\u7247\u4f7f\u7528\u4e86\u53c8\u62cd\u4e91\u7684CDN\u670d\u52a1\uff0c\u7b2c\u4e8c\u90e8\u5206\u5373\u662f\u4e0a\u9762\u7684 <code>pins[0].file.key<\/code> \u52a0\u4e0a\u4e00\u4e2a <code>_fw236<\/code> \u540e\u7f00\uff1b\u5176\u5b83\u56fe\u7247\u7684 <code>src<\/code> \u90fd\u5e26\u6709\u8fd9\u4e2a <code>_fw236<\/code> \u540e\u7f00\uff0c\u6682\u65f6\u8fd8\u4e0d\u77e5\u9053\u5b83\u7684\u610f\u4e49\u3002<\/p>\n<p>\u62ff\u5230\u4e86\u753b\u677f\u56fe\u7247\u4fe1\u606f\uff0c\u5230\u8fd9\u4e00\u6b65\u5c31\u80fd\u60f3\u5230\u53ef\u4ee5\u901a\u8fc7\u722c\u866b\u6765\u4e0b\u8f7d\u753b\u677f\u7684\u56fe\u7247\u3002<\/p>\n<h3 id=\"\u56fe\u7247\u61d2\u52a0\u8f7d\">\u56fe\u7247\u61d2\u52a0\u8f7d<\/h3>\n<p>\u518d\u56de\u5230\u753b\u677f\u7f51\u9875\u4e0a\uff0c\u770b\u5230\u9875\u9762\u4e0a\u76ee\u524d\u53ea\u52a0\u8f7d\u4e86\u753b\u677f\u4e00\u90e8\u5206\u56fe\u7247\uff0c\u5269\u4e0b\u7684\u56fe\u7247\u662f\u901a\u8fc7<strong>\u61d2\u52a0\u8f7d<\/strong>\u7684\u65b9\u5f0f\u51fa\u73b0\u7684\uff08\u60f3\u60f3\u5c31\u77e5\u9053\u4e0d\u80fd\u4e00\u6b21\u6027\u628a\u6240\u6709\u56fe\u7247\u90fd\u52a0\u8f7d\u51fa\u6765\uff09\u3002<\/p>\n<p>\u62d6\u52a8\u6eda\u52a8\u6761\u5230\u5e95\u90e8\uff0c\u7ee7\u7eed\u89c2\u5bdf <strong>Network<\/strong>\uff0c\u7b2c\u4e00\u4e2a\u8bf7\u6c42 <a href=\"http:\/\/huaban.com\/boards\/17473820\/?jg6ltavl&amp;max=1584529804&amp;limit=20&amp;wfl=1\">http:\/\/huaban.com\/boards\/17473820\/?jg6ltavl&amp;max=1584529804&amp;limit=20&amp;wfl=1<\/a> \u5728\u753b\u677fID\u540e\u9762\u643a\u5e26\u4e86\u4e00\u4e9b\u53c2\u6570\uff1a<\/p>\n<p><img src=\"https:\/\/jancat.github.io\/images\/post\/huaban-crawler-with-node-and-typescript\/board-lazy-load.png\" alt=\"board-lazy-load\"><\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-js\" data-lang=\"js\"><span class=\"nx\">jg6ltavl<\/span><span class=\"o\">:<\/span> \n<span class=\"nx\">max<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1584529804<\/span>\n<span class=\"nx\">limit<\/span><span class=\"o\">:<\/span> <span class=\"mi\">20<\/span>\n<span class=\"nx\">wfl<\/span><span class=\"o\">:<\/span> <span class=\"mi\">1<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><ul>\n<li>\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u4e2a\u968f\u673a\u5b57\u7b26\u4e32\uff0c\u6700\u540e\u4e00\u4f4d\u6309\u5b57\u6bcd\u8868\u987a\u5e8f\u5faa\u73af\uff0c\u6ca1\u53d1\u73b0\u6709\u4ec0\u4e48\u610f\u4e49\uff0c\u5ffd\u7565\uff1b<\/li>\n<li>\u7b2c\u4e8c\u4e2a\u53c2\u6570 <strong>max<\/strong> \u7684\u503c\u662f\u4e2a <strong>pin_id<\/strong> \uff1b<\/li>\n<li>\u7b2c\u4e09\u4e2a\u53c2\u6570 <strong>limit<\/strong> \u9650\u5236\u4e86\u670d\u52a1\u5668\u8fd4\u56de\u7684 <strong>pin \u6570\u91cf<\/strong>\uff1b<\/li>\n<li>\u7b2c\u56db\u4e2a\u53c2\u6570 <strong>wfl<\/strong> \u53ef\u80fd\u662f <strong>waterfall<\/strong> \u7011\u5e03\u6d41\u7684\u7f29\u5199\uff0c\u6ca1\u53d1\u73b0\u6709\u4ec0\u4e48\u610f\u4e49\uff0c\u5ffd\u7565\u3002<\/li>\n<\/ul>\n<p>\u91cd\u70b9\u662f <strong>max<\/strong> \u548c <strong>limit<\/strong> \u8fd9\u4e24\u4e2a\u503c\uff0c\u7ecf\u8fc7\u6d4b\u8bd5\u53d1\u73b0\uff0c<strong>max<\/strong> \u662f\u4e0a\u4e00\u5f20\u56fe\u7247\u7684 <strong>pin_id<\/strong>\uff0c\u670d\u52a1\u5668\u6309\u5148\u540e\u987a\u5e8f\uff08\u91c7\u96c6\u987a\u5e8f\uff09\u8fd4\u56de\u8fd9\u5f20\u56fe\u7247<strong>\u540e\u9762<\/strong>\u7684 pin \u6570\u636e\uff1b<\/p>\n<p>\u800c <strong>limit<\/strong> \u544a\u8bc9\u670d\u52a1\u5668\u8fd4\u56de<strong>\u591a\u5c11\u4e2a<\/strong> pin \u6570\u636e\u3002\u540e\u9762\u6d4b\u51fa\u670d\u52a1\u5668\u5bf9 <strong>limit<\/strong> \u505a\u4e86\u6700\u5927\u503c\u6821\u9a8c\uff0c\u6700\u5927\u662f <strong>100<\/strong>\uff0c\u5373\u4e00\u6b21\u6700\u591a\u53ea\u80fd\u52a0\u8f7d100\u5f20\u56fe\u7247\u6570\u636e\u3002<\/p>\n<p>\u5230\u4e86\u73b0\u5728\u53ef\u4ee5\u5f00\u59cb\u5199\u722c\u866b\u6a21\u62df\u4e0a\u9762\u7684\u64cd\u4f5c\u4e86\u3002<\/p>\n<h2 id=\"node-\u722c\u866b\u5b9e\u73b0\">Node \u722c\u866b\u5b9e\u73b0<\/h2>\n<p>\u4f7f\u7528 Node.js \u5b9e\u73b0\u547d\u4ee4\u884c\u7a0b\u5e8f\uff0c\u63d0\u4f9b\u4e24\u79cd\u65b9\u5f0f\u4e0b\u8f7d\u56fe\u7247\uff1a<\/p>\n<ol>\n<li>\u8f93\u5165<strong>\u753b\u677fID<\/strong>\u4e0b\u8f7d\u8be5\u753b\u677f\u7684\u6240\u6709\u56fe\u7247<\/li>\n<li>\u8f93\u5165<strong>\u7528\u6237ID<\/strong>\u4e0b\u8f7d\u8be5\u7528\u6237\u6240\u6709\u81ea\u5efa\u753b\u677f\u7684\u56fe\u7247\uff08\u4e0d\u5305\u62ec\u6536\u85cf\u7684\u753b\u677f\uff09<\/li>\n<\/ol>\n<h3 id=\"\u8f93\u5165\u753b\u677fid\u4e0b\u8f7d\u8be5\u753b\u677f\u7684\u6240\u6709\u56fe\u7247\">\u8f93\u5165\u753b\u677fID\u4e0b\u8f7d\u8be5\u753b\u677f\u7684\u6240\u6709\u56fe\u7247<\/h3>\n<ol>\n<li>\n<p>\u5728\u547d\u4ee4\u884c\u4e2d\u8ddf\u7528\u6237\u4ea4\u4e92\uff0c\u4f7f\u7528 Node <code>readline<\/code> API\u5b9e\u73b0\u5728 <code>stdin\/stdout<\/code> \u8bfb\u53d6\u8f93\u5165\u548c\u663e\u793a\u8f93\u51fa\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"kr\">import<\/span> <span class=\"nx\">readline<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">&#39;readline&#39;<\/span>\n\n<span class=\"kr\">const<\/span> <span class=\"nx\">rl<\/span>: <span class=\"kt\">readline.ReadLine<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">readline<\/span><span class=\"p\">.<\/span><span class=\"nx\">createInterface<\/span><span class=\"p\">({<\/span>\n  <span class=\"nx\">input<\/span>: <span class=\"kt\">process.stdin<\/span><span class=\"p\">,<\/span>\n  <span class=\"nx\">output<\/span>: <span class=\"kt\">process.stdout<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">})<\/span>\n<span class=\"nx\">rl<\/span><span class=\"p\">.<\/span><span class=\"nx\">question<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\u753b\u677fID\uff1a&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">boardId<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{})<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u9996\u5148\u6839\u636e\u753b\u677fID\u83b7\u53d6 <code>board<\/code> \u6570\u636e\uff0c\u7136\u540e\u83b7\u53d6\u5230 <code>board<\/code> \u4e2d\u6240\u6709\u7684 <code>pins<\/code> \u6570\u636e\uff0c\u6700\u540e\u6839\u636e\u6bcf\u4e2a <code>pin<\/code> \u6570\u636e\u4e0b\u8f7d\u56fe\u7247\u5230\u672c\u5730\u76ee\u5f55\u4e2d\uff0c\u4e2d\u95f4\u5411\u547d\u4ee4\u884c\u4e2d\u8f93\u51fa\u4e00\u4e9b\u63d0\u793a\uff1a<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><span class=\"lnt\">2\n<\/span><span class=\"lnt\">3\n<\/span><span class=\"lnt\">4\n<\/span><span class=\"lnt\">5\n<\/span><span class=\"lnt\">6\n<\/span><span class=\"lnt\">7\n<\/span><span class=\"lnt\">8\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">downloadSingleBoard<\/span><span class=\"p\">(<\/span><span class=\"nx\">boardId<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">void<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">time<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Total time&#39;<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">board<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">getBoardInfo<\/span><span class=\"p\">(<\/span><span class=\"nx\">boardId<\/span><span class=\"p\">)<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\\n\u5f00\u59cb\u4e0b\u8f7d\u753b\u677f %s - %s\uff0c\u56fe\u7247\u6570\u91cf\uff1a%d&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">boardId<\/span><span class=\"p\">,<\/span> <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">title<\/span><span class=\"p\">,<\/span> <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pin_count<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"k\">await<\/span> <span class=\"nx\">getPinsAndDownload<\/span><span class=\"p\">(<\/span><span class=\"nx\">board<\/span><span class=\"p\">)<\/span>\n  <span class=\"nx\">outputResult<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u6839\u636e\u753b\u677fID\u83b7\u53d6 <code>board<\/code> \u6570\u636e\u3002\u4e3a\u4e86\u4f7f\u7528 ES7 \u7684 <code>async\/await<\/code>\uff0c\u5f15\u5165\u4e86 <code>promisify<\/code> \u7684 request \u5e93<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-typescript\" data-lang=\"typescript\"><span class=\"kr\">import<\/span> <span class=\"nx\">rp<\/span> <span class=\"kr\">from<\/span> <span class=\"s1\">&#39;request-promise&#39;<\/span>\n\n<span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">getBoardInfo<\/span><span class=\"p\">(<\/span><span class=\"nx\">boardId<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">IBoard<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">response<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">err?<\/span>: <span class=\"kt\">number<\/span>\n    <span class=\"nx\">board<\/span>: <span class=\"kt\">IBoard<\/span>\n  <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">rp<\/span><span class=\"p\">({<\/span>\n    <span class=\"nx\">uri<\/span><span class=\"o\">:<\/span> <span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">huabanDomain<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/boards\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">boardId<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/`<\/span><span class=\"p\">,<\/span>\n    <span class=\"nx\">headers<\/span>: <span class=\"kt\">jsonRequestHeader<\/span><span class=\"p\">,<\/span>\n    <span class=\"nx\">qs<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">limit<\/span>: <span class=\"kt\">1<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">},<\/span>\n    <span class=\"nx\">json<\/span>: <span class=\"kt\">true<\/span><span class=\"p\">,<\/span>\n  <span class=\"p\">})<\/span>\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">err<\/span> <span class=\"o\">===<\/span> <span class=\"mi\">404<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Error<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\u753b\u677f\u4e0d\u5b58\u5728\uff01&#39;<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"k\">return<\/span> <span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">board<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u83b7\u53d6 <code>pins<\/code> \u6570\u636e\u7136\u540e\u4e0b\u8f7d\u56fe\u7247\uff0c\u8f93\u51fa\u7ed3\u679c\u3002\u5176\u4e2d\u5728\u83b7\u53d6 <code>pins<\/code> \u6570\u636e\u7684\u65f6\u5019\u53d1\u73b0\u6709\u4e9b\u753b\u677f\u65e0\u6cd5\u83b7\u53d6\u5168\u90e8\u7684 <code>pins<\/code> \u6570\u636e\uff0c\u9020\u6210\u753b\u677f\u56fe\u7247\u4e0b\u8f7d\u4e0d\u5168\uff08\u6682\u65f6\u8fd8\u4e0d\u6e05\u695a\u539f\u56e0\uff09<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">getPinsAndDownload<\/span><span class=\"p\">(<\/span><span class=\"nx\">board<\/span>: <span class=\"kt\">IBoard<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">void<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">boardPins<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">getPins<\/span><span class=\"p\">(<\/span><span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">board_id<\/span><span class=\"p\">)<\/span>\n  <span class=\"c1\">\/\/ TODO: \u6709\u4e9b\u753b\u677f\u83b7\u53d6\u7684pins\u6570\u636e\u4e0d\u5168\uff1f\n<\/span><span class=\"c1\"><\/span>  <span class=\"kr\">const<\/span> <span class=\"nx\">missedPinsCount<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pin_count<\/span> <span class=\"o\">-<\/span> <span class=\"nx\">boardPins<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span>\n\n  <span class=\"kr\">const<\/span> <span class=\"nx\">boardPath<\/span> <span class=\"o\">=<\/span> <span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">downloadPath<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">board_id<\/span><span class=\"si\">}<\/span><span class=\"sb\"> - <\/span><span class=\"si\">${<\/span><span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">title<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span>\n  <span class=\"nx\">fs<\/span><span class=\"p\">.<\/span><span class=\"nx\">emptyDirSync<\/span><span class=\"p\">(<\/span><span class=\"nx\">boardPath<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"kr\">const<\/span> <span class=\"nx\">downloadCount<\/span>: <span class=\"kt\">number<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">downloadImage<\/span><span class=\"p\">(<\/span><span class=\"nx\">boardPins<\/span><span class=\"p\">,<\/span> <span class=\"nx\">boardPath<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">failedCount<\/span>: <span class=\"kt\">number<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pin_count<\/span> <span class=\"o\">-<\/span> <span class=\"nx\">downloadCount<\/span> <span class=\"o\">-<\/span> <span class=\"nx\">missedPinsCount<\/span>\n  <span class=\"nx\">totalDownload<\/span> <span class=\"o\">+=<\/span> <span class=\"nx\">downloadCount<\/span>\n\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span>\n    <span class=\"sb\">`Done. \u6210\u529f %d \u4e2a<\/span><span class=\"si\">${<\/span><span class=\"nx\">failedCount<\/span> <span class=\"o\">?<\/span> <span class=\"sb\">`\uff0c\u5931\u8d25 <\/span><span class=\"err\">\\<\/span><span class=\"sb\">x1b[31m<\/span><span class=\"si\">${<\/span><span class=\"nx\">failedCount<\/span><span class=\"si\">}<\/span><span class=\"err\">\\<\/span><span class=\"sb\">x1b[0m\u4e2a`<\/span> <span class=\"o\">:<\/span> <span class=\"s1\">&#39;&#39;<\/span><span class=\"si\">}${<\/span>\n      <span class=\"nx\">missedPinsCount<\/span> <span class=\"o\">?<\/span> <span class=\"sb\">`\uff0c\u4e22\u5931 <\/span><span class=\"err\">\\<\/span><span class=\"sb\">x1b[31m<\/span><span class=\"si\">${<\/span><span class=\"nx\">missedPinsCount<\/span><span class=\"si\">}<\/span><span class=\"err\">\\<\/span><span class=\"sb\">x1b[0m \u4e2a`<\/span> <span class=\"o\">:<\/span> <span class=\"s1\">&#39;&#39;<\/span>\n    <span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">,<\/span>\n    <span class=\"nx\">downloadCount<\/span><span class=\"p\">,<\/span>\n  <span class=\"p\">)<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u83b7\u53d6\u753b\u677f\u4e2d\u5168\u90e8pins(\u56fe\u7247)\u6570\u636e\u3002\u6709\u4e2a\u5173\u952e\u7684\u70b9\uff0c\u8bf7\u6c42\u5934\u90e8\u4e2d\u5982\u679c\u4e0d\u52a0\u4e0a <code>'X-Requested-With': 'XMLHttpRequest'<\/code>\uff0c\u670d\u52a1\u5668\u8fd4\u56de\u7684\u662f\u5305\u542bjson\u7684HMLT Document\uff0c\u800c\u4e0d\u662f\u5355\u7eaf\u7684 <code>json<\/code> \u6570\u636e\u3002\u6211\u770b\u5230\u6709\u4e9b\u811a\u672c\u6ca1\u6709\u6ce8\u610f\u5230\u8fd9\u70b9\uff0c\u5c31\u9700\u8981\u7528\u6b63\u5219\u622a\u53d6HTML\u4e2d\u7684 <code>json<\/code>\uff0c\u591a\u8d70\u4e86\u4e00\u6b65\u5f2f\u8def\uff08\u6211\u4e5f\u662f\u4ece\u5f2f\u8def\u8d70\u8fc7\u6765\u7684\uff0c\u8fd9\u91cc\u63d0\u9192\u540e\u9762\u7684\u8bfb\u8005\uff09<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><span class=\"lnt\">36\n<\/span><span class=\"lnt\">37\n<\/span><span class=\"lnt\">38\n<\/span><span class=\"lnt\">39\n<\/span><span class=\"lnt\">40\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"c1\">\/\/ \u5173\u952e\u5934\u90e8\uff0c\u6dfb\u52a0\u8be5\u9879\u540e\u670d\u52a1\u5668\u53ea\u4f1a\u8fd4\u56dejson\u6570\u636e\uff0c\u800c\u4e0d\u662f\u5305\u542bjson\u7684HTML\n<\/span><span class=\"c1\"><\/span><span class=\"kr\">const<\/span> <span class=\"nx\">jsonRequestHeader<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">Accept<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;application\/json&#39;<\/span><span class=\"p\">,<\/span>\n  <span class=\"s1\">&#39;X-Requested-With&#39;<\/span><span class=\"o\">:<\/span> <span class=\"s1\">&#39;XMLHttpRequest&#39;<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">getPins<\/span><span class=\"p\">(<\/span><span class=\"nx\">boardId<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">IPin<\/span><span class=\"err\">[]<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">allPins<\/span>: <span class=\"kt\">IPin<\/span><span class=\"p\">[]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n\n  <span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">loadPins<\/span><span class=\"p\">(<\/span><span class=\"nx\">lastPinId<\/span>: <span class=\"kt\">string<\/span> <span class=\"o\">=<\/span> <span class=\"s1\">&#39;&#39;<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">void<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ limit \u67e5\u8be2\u53c2\u6570\u9650\u5236\u83b7\u53d6\u7684pin\u6570\u91cf\uff0c\u6700\u5927100\uff0c\u9ed8\u8ba420\n<\/span><span class=\"c1\"><\/span>    <span class=\"kr\">const<\/span> <span class=\"nx\">response<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">rp<\/span><span class=\"p\">({<\/span>\n      <span class=\"nx\">uri<\/span><span class=\"o\">:<\/span> <span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">huabanDomain<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/boards\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">boardId<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/`<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">qs<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">limit<\/span>: <span class=\"kt\">100<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">max<\/span>: <span class=\"kt\">lastPinId<\/span><span class=\"p\">,<\/span>\n      <span class=\"p\">},<\/span>\n      <span class=\"nx\">headers<\/span>: <span class=\"kt\">jsonRequestHeader<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">json<\/span>: <span class=\"kt\">true<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">})<\/span>\n\n    <span class=\"kr\">const<\/span> <span class=\"nx\">board<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">board<\/span>\n    <span class=\"c1\">\/\/ if (response.headers[&#39;content-type&#39;]!.includes(&#39;text\/html&#39;)) {\n<\/span><span class=\"c1\"><\/span>    <span class=\"c1\">\/\/   \/\/ \u5339\u914d boards json \u4e32\n<\/span><span class=\"c1\"><\/span>    <span class=\"c1\">\/\/   const boardJson: string = \/app\\.page\\[&#34;board&#34;\\]\\s=\\s({.*});\/.exec(response)![1]\n<\/span><span class=\"c1\"><\/span>    <span class=\"c1\">\/\/   board = JSON.parse(boardJson)\n<\/span><span class=\"c1\"><\/span>    <span class=\"c1\">\/\/ }\n<\/span><span class=\"c1\"><\/span>    <span class=\"nx\">allPins<\/span><span class=\"p\">.<\/span><span class=\"nx\">push<\/span><span class=\"p\">(...<\/span><span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pins<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"c1\">\/\/ \u5f53\u6b64\u6b21\u83b7\u53d6\u7684pins\u4e3a\u7a7a\u6216\u8005\u5168\u90e8pins\u5df2\u83b7\u53d6\u5b8c\uff0c\u5219\u8fd4\u56de\n<\/span><span class=\"c1\"><\/span>    <span class=\"kr\">const<\/span> <span class=\"nx\">pinsChunkLength<\/span>: <span class=\"kt\">number<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pins<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">pinsChunkLength<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">allPins<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pin_count<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"c1\">\/\/ \u7528\u6700\u540e\u4e00\u4e2apin id\u4f5c\u4e3a\u4e0b\u4e00\u6b21\u8bf7\u6c42\u7684max\u503c\uff0c\u8868\u793a\u83b7\u53d6\u8be5pin\u540e\u9762\u7684pins\n<\/span><span class=\"c1\"><\/span>      <span class=\"k\">await<\/span> <span class=\"nx\">loadPins<\/span><span class=\"p\">(<\/span><span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pins<\/span><span class=\"p\">[<\/span><span class=\"nx\">pinsChunkLength<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">1<\/span><span class=\"p\">].<\/span><span class=\"nx\">pin_id<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"k\">await<\/span> <span class=\"nx\">loadPins<\/span><span class=\"p\">()<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">allPins<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u6839\u636e <code>pins<\/code> \u4e0b\u8f7d\u56fe\u7247\u3002\u8fd9\u91cc\u5f15\u5165\u4e86 <code>async<\/code> \u5f02\u6b65\u5e93\u6765\u63a7\u5236\u540c\u4e00\u65f6\u95f4\u7684\u4e0b\u8f7d\u5e76\u53d1\u6570\uff0c\u5426\u5219\u5e76\u53d1\u8fc7\u9ad8<strong>Node\u4f1a\u5931\u53bb\u54cd\u5e94<\/strong>\uff1b\u4e0b\u8f7d\u5931\u8d25\u7684\u56fe\u7247\u8fd8\u4f1a\u91cd\u8bd5\u4e00\u6b21<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><span class=\"lnt\">36\n<\/span><span class=\"lnt\">37\n<\/span><span class=\"lnt\">38\n<\/span><span class=\"lnt\">39\n<\/span><span class=\"lnt\">40\n<\/span><span class=\"lnt\">41\n<\/span><span class=\"lnt\">42\n<\/span><span class=\"lnt\">43\n<\/span><span class=\"lnt\">44\n<\/span><span class=\"lnt\">45\n<\/span><span class=\"lnt\">46\n<\/span><span class=\"lnt\">47\n<\/span><span class=\"lnt\">48\n<\/span><span class=\"lnt\">49\n<\/span><span class=\"lnt\">50\n<\/span><span class=\"lnt\">51\n<\/span><span class=\"lnt\">52\n<\/span><span class=\"lnt\">53\n<\/span><span class=\"lnt\">54\n<\/span><span class=\"lnt\">55\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">downloadImage<\/span><span class=\"p\">(<\/span><span class=\"nx\">allPins<\/span>: <span class=\"kt\">IPin<\/span><span class=\"p\">[],<\/span> <span class=\"nx\">boardPath<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">number<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">let<\/span> <span class=\"nx\">downloadCount<\/span>: <span class=\"kt\">number<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">errorImageUrl<\/span>: <span class=\"kt\">Array<\/span><span class=\"o\">&lt;<\/span><span class=\"p\">{<\/span> <span class=\"nx\">url<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">;<\/span> <span class=\"nx\">path<\/span>: <span class=\"kt\">string<\/span> <span class=\"p\">}<\/span><span class=\"o\">&gt;<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n\n  <span class=\"c1\">\/\/ \u91cd\u8bd5\u4e0b\u8f7d\u5931\u8d25\u7684\u56fe\u7247\n<\/span><span class=\"c1\"><\/span>  <span class=\"kd\">function<\/span> <span class=\"nx\">retry() {<\/span>\n    <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kr\">const<\/span> <span class=\"nx\">image<\/span> <span class=\"k\">of<\/span> <span class=\"nx\">errorImageUrl<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">rp<\/span><span class=\"p\">({<\/span>\n        <span class=\"nx\">uri<\/span>: <span class=\"kt\">image.url<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">timeout<\/span>: <span class=\"kt\">20<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">1000<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">encoding<\/span>: <span class=\"kt\">null<\/span><span class=\"p\">,<\/span> <span class=\"c1\">\/\/ make response a Buffer to write image correctly\n<\/span><span class=\"c1\"><\/span>      <span class=\"p\">}).<\/span><span class=\"nx\">pipe<\/span><span class=\"p\">(<\/span>\n        <span class=\"nx\">fs<\/span><span class=\"p\">.<\/span><span class=\"nx\">createWriteStream<\/span><span class=\"p\">(<\/span><span class=\"nx\">image<\/span><span class=\"p\">.<\/span><span class=\"nx\">path<\/span><span class=\"p\">).<\/span><span class=\"nx\">on<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;finish&#39;<\/span><span class=\"p\">,<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n          <span class=\"nx\">totalDownload<\/span><span class=\"o\">++<\/span>\n          <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\\x1b[32m Retry ok! \\x1b[0m %s&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">image<\/span><span class=\"p\">.<\/span><span class=\"nx\">url<\/span><span class=\"p\">)<\/span>\n        <span class=\"p\">}),<\/span>\n      <span class=\"p\">)<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"kd\">function<\/span> <span class=\"nx\">download<\/span><span class=\"p\">(<\/span><span class=\"nx\">pin<\/span>: <span class=\"kt\">IPin<\/span><span class=\"p\">,<\/span> <span class=\"nx\">cb<\/span><span class=\"o\">:<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">void<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"k\">void<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">imageUrl<\/span>: <span class=\"kt\">string<\/span> <span class=\"o\">=<\/span> <span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">imageServer<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">pin<\/span><span class=\"p\">.<\/span><span class=\"nx\">file<\/span><span class=\"p\">.<\/span><span class=\"nx\">key<\/span><span class=\"si\">}<\/span><span class=\"sb\">_fw658`<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">imageName<\/span>: <span class=\"kt\">string<\/span> <span class=\"o\">=<\/span> <span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">pin<\/span><span class=\"p\">.<\/span><span class=\"nx\">pin_id<\/span><span class=\"si\">}${<\/span><span class=\"nx\">imagesTypes<\/span><span class=\"p\">[<\/span><span class=\"nx\">pin<\/span><span class=\"p\">.<\/span><span class=\"nx\">file<\/span><span class=\"p\">.<\/span><span class=\"kr\">type<\/span><span class=\"p\">]<\/span> <span class=\"o\">||<\/span> <span class=\"s1\">&#39;.jpg&#39;<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span>\n\n    <span class=\"nx\">rp<\/span><span class=\"p\">({<\/span>\n      <span class=\"nx\">uri<\/span>: <span class=\"kt\">imageUrl<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">timeout<\/span>: <span class=\"kt\">20<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">1000<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">encoding<\/span>: <span class=\"kt\">null<\/span><span class=\"p\">,<\/span> <span class=\"c1\">\/\/ make response a Buffer to write image correctly\n<\/span><span class=\"c1\"><\/span>    <span class=\"p\">})<\/span>\n      <span class=\"p\">.<\/span><span class=\"nx\">then<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">downloadCount<\/span><span class=\"o\">++<\/span>\n\n        <span class=\"nx\">fs<\/span><span class=\"p\">.<\/span><span class=\"nx\">writeFile<\/span><span class=\"p\">(<\/span><span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">boardPath<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">imageName<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span><span class=\"p\">,<\/span> <span class=\"nx\">data<\/span><span class=\"p\">,<\/span> <span class=\"nx\">error<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n          <span class=\"nx\">error<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">error<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\\x1b[31m%s\\x1b[0m%s&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">message<\/span><span class=\"p\">,<\/span> <span class=\"nx\">imageUrl<\/span><span class=\"p\">)<\/span>\n        <span class=\"p\">})<\/span>\n      <span class=\"p\">})<\/span>\n      <span class=\"p\">.<\/span><span class=\"k\">catch<\/span><span class=\"p\">(<\/span><span class=\"nx\">error<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">error<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\\x1b[31m%s %s.\\x1b[0m %s&#39;<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;Download image failed.&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">error<\/span><span class=\"p\">.<\/span><span class=\"nx\">message<\/span><span class=\"p\">,<\/span> <span class=\"nx\">imageUrl<\/span><span class=\"p\">)<\/span>\n        <span class=\"nx\">errorImageUrl<\/span><span class=\"p\">.<\/span><span class=\"nx\">push<\/span><span class=\"p\">({<\/span> <span class=\"nx\">url<\/span>: <span class=\"kt\">imageUrl<\/span><span class=\"p\">,<\/span> <span class=\"nx\">path<\/span><span class=\"o\">:<\/span> <span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">boardPath<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">imageName<\/span><span class=\"si\">}<\/span><span class=\"sb\">`<\/span> <span class=\"p\">})<\/span>\n      <span class=\"p\">})<\/span>\n      <span class=\"p\">.<\/span><span class=\"k\">finally<\/span><span class=\"p\">(<\/span><span class=\"nx\">cb<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"c1\">\/\/ async\u63a7\u5236\u5e76\u53d1\u4e0b\u8f7d\u6570\uff0c\u5426\u5219\u5e76\u53d1\u6570\u592a\u9ad8Node\u4f1a\u5931\u53bb\u54cd\u5e94\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">number<\/span><span class=\"p\">&gt;(<\/span><span class=\"nx\">resolve<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ \u540c\u4e00\u65f6\u95f4\u6700\u591a\u670910\u4e2a(\u4e0d\u80fd\u592a\u9ad8)\u5e76\u53d1\u8bf7\u6c42\n<\/span><span class=\"c1\"><\/span>    <span class=\"kr\">async<\/span><span class=\"p\">.<\/span><span class=\"nx\">eachLimit<\/span><span class=\"p\">(<\/span><span class=\"nx\">allPins<\/span><span class=\"p\">,<\/span> <span class=\"mi\">10<\/span><span class=\"p\">,<\/span> <span class=\"nx\">download<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nx\">error<\/span>: <span class=\"kt\">IError<\/span> <span class=\"o\">|<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">error<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">throw<\/span> <span class=\"nx\">error<\/span>\n      <span class=\"p\">}<\/span>\n      <span class=\"nx\">errorImageUrl<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">retry<\/span><span class=\"p\">()<\/span>\n      <span class=\"nx\">resolve<\/span><span class=\"p\">(<\/span><span class=\"nx\">downloadCount<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">})<\/span>\n  <span class=\"p\">})<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u4e0b\u8f7d\u7684\u56fe\u7247\u4f1a\u4fdd\u5b58\u5728\u9ed8\u8ba4 <code>images<\/code> \u76ee\u5f55\u6216\u8005\u7528\u6237\u8f93\u5165\u7684\u6307\u5b9a\u76ee\u5f55\u4e2d\uff0c\u4e0b\u8f7d\u901f\u5ea6\u5e73\u5747 5 \u5f20\/\u79d2<\/p>\n<\/li>\n<\/ol>\n<h3 id=\"\u8f93\u5165\u7528\u6237id\u4e0b\u8f7d\u8be5\u7528\u6237\u6240\u6709\u81ea\u5efa\u753b\u677f\u7684\u56fe\u7247\u4e0d\u5305\u62ec\u6536\u85cf\u7684\u753b\u677f\">\u8f93\u5165\u7528\u6237ID\u4e0b\u8f7d\u8be5\u7528\u6237\u6240\u6709\u81ea\u5efa\u753b\u677f\u7684\u56fe\u7247\uff08\u4e0d\u5305\u62ec\u6536\u85cf\u7684\u753b\u677f\uff09<\/h3>\n<ol>\n<li>\n<p>\u547d\u4ee4\u884c\u4e2d\u8f93\u5165\u7528\u6237ID<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\">1\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"nx\">rl<\/span><span class=\"p\">.<\/span><span class=\"nx\">question<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\u8bf7\u8f93\u5165\u5730\u5740\u680f\u4e2d\u7684\u7528\u6237\u540d\uff1a&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">username<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{})<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u9996\u5148\u83b7\u53d6\u5230\u8be5\u7528\u6237\u7684\u6240\u6709\u753b\u677f\u6570\u636e\uff0c\u7136\u540e\u987a\u5e8f\u4e0b\u8f7d\u6bcf\u4e2a\u753b\u677f\u4e2d\u7684\u56fe\u7247<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">downloadBoardsOfUser<\/span><span class=\"p\">(<\/span><span class=\"nx\">username<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">void<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">time<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;Total time&#39;<\/span><span class=\"p\">)<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">userBoards<\/span>: <span class=\"kt\">IBoard<\/span><span class=\"p\">[]<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">getUserBoards<\/span><span class=\"p\">(<\/span><span class=\"nx\">username<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\\n\u7528\u6237 [%s] \u753b\u677f\u6570\u91cf\uff1a%d&#39;<\/span><span class=\"p\">,<\/span> <span class=\"nx\">username<\/span><span class=\"p\">,<\/span> <span class=\"nx\">userBoards<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span><span class=\"p\">)<\/span>\n\n  <span class=\"c1\">\/\/ \u987a\u5e8f\u4e0b\u8f7d\u753b\u677f\uff0c\u5e76\u884c\u4e0b\u8f7d\u4f1a\u5931\u63a7\n<\/span><span class=\"c1\"><\/span>  <span class=\"k\">for<\/span> <span class=\"p\">(<\/span><span class=\"kr\">const<\/span> <span class=\"nx\">board<\/span> <span class=\"k\">of<\/span> <span class=\"nx\">userBoards<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nx\">log<\/span><span class=\"p\">(<\/span>\n      <span class=\"s1\">&#39;\\n\u5f00\u59cb\u4e0b\u8f7d\u753b\u677f\uff1a[%s - %s]\uff0c\u56fe\u7247\u6570\u91cf\uff1a%d&#39;<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">board_id<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">title<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">board<\/span><span class=\"p\">.<\/span><span class=\"nx\">pin_count<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">)<\/span>\n    <span class=\"k\">await<\/span> <span class=\"nx\">getPinsAndDownload<\/span><span class=\"p\">(<\/span><span class=\"nx\">board<\/span><span class=\"p\">)<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"nx\">outputResult<\/span><span class=\"p\">()<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u83b7\u53d6\u7528\u6237\u753b\u677f\u3002\u7528\u6237\u753b\u677f\u4e5f\u4f7f\u7528\u4e86\u61d2\u52a0\u8f7d\u65b9\u5f0f\uff0c\u6240\u4ee5\u4e5f\u9700\u8981\u53bb\u5faa\u73af\u83b7\u53d6<\/p>\n<div class=\"highlight\"><div class=\"chroma\">\n<table class=\"lntable\"><tr><td class=\"lntd\">\n<pre class=\"chroma\"><code><span class=\"lnt\"> 1\n<\/span><span class=\"lnt\"> 2\n<\/span><span class=\"lnt\"> 3\n<\/span><span class=\"lnt\"> 4\n<\/span><span class=\"lnt\"> 5\n<\/span><span class=\"lnt\"> 6\n<\/span><span class=\"lnt\"> 7\n<\/span><span class=\"lnt\"> 8\n<\/span><span class=\"lnt\"> 9\n<\/span><span class=\"lnt\">10\n<\/span><span class=\"lnt\">11\n<\/span><span class=\"lnt\">12\n<\/span><span class=\"lnt\">13\n<\/span><span class=\"lnt\">14\n<\/span><span class=\"lnt\">15\n<\/span><span class=\"lnt\">16\n<\/span><span class=\"lnt\">17\n<\/span><span class=\"lnt\">18\n<\/span><span class=\"lnt\">19\n<\/span><span class=\"lnt\">20\n<\/span><span class=\"lnt\">21\n<\/span><span class=\"lnt\">22\n<\/span><span class=\"lnt\">23\n<\/span><span class=\"lnt\">24\n<\/span><span class=\"lnt\">25\n<\/span><span class=\"lnt\">26\n<\/span><span class=\"lnt\">27\n<\/span><span class=\"lnt\">28\n<\/span><span class=\"lnt\">29\n<\/span><span class=\"lnt\">30\n<\/span><span class=\"lnt\">31\n<\/span><span class=\"lnt\">32\n<\/span><span class=\"lnt\">33\n<\/span><span class=\"lnt\">34\n<\/span><span class=\"lnt\">35\n<\/span><span class=\"lnt\">36\n<\/span><\/code><\/pre><\/td>\n<td class=\"lntd\">\n<pre class=\"chroma\"><code class=\"language-ts\" data-lang=\"ts\"><span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">getUserBoards<\/span><span class=\"p\">(<\/span><span class=\"nx\">username<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">IBoard<\/span><span class=\"err\">[]<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kr\">const<\/span> <span class=\"nx\">allUserBoards<\/span>: <span class=\"kt\">IBoard<\/span><span class=\"p\">[]<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n\n  <span class=\"kr\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nx\">getBoards<\/span><span class=\"p\">(<\/span><span class=\"nx\">lastBoardId?<\/span>: <span class=\"kt\">string<\/span><span class=\"p\">)<\/span><span class=\"o\">:<\/span> <span class=\"nx\">Promise<\/span><span class=\"p\">&lt;<\/span><span class=\"nt\">void<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">response<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span>\n      <span class=\"nx\">err?<\/span>: <span class=\"kt\">number<\/span>\n      <span class=\"nx\">user?<\/span>: <span class=\"kt\">IUser<\/span>\n    <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">rp<\/span><span class=\"p\">({<\/span>\n      <span class=\"nx\">uri<\/span><span class=\"o\">:<\/span> <span class=\"sb\">`<\/span><span class=\"si\">${<\/span><span class=\"nx\">huabanDomain<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/<\/span><span class=\"si\">${<\/span><span class=\"nx\">username<\/span><span class=\"si\">}<\/span><span class=\"sb\">\/`<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">qs<\/span><span class=\"o\">:<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">limit<\/span>: <span class=\"kt\">100<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">max<\/span>: <span class=\"kt\">lastBoardId<\/span><span class=\"p\">,<\/span>\n      <span class=\"p\">},<\/span>\n      <span class=\"nx\">headers<\/span>: <span class=\"kt\">jsonRequestHeader<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">json<\/span>: <span class=\"kt\">true<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">})<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">err<\/span> <span class=\"o\">===<\/span> <span class=\"mi\">404<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Error<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\u7528\u6237\u4e0d\u5b58\u5728\uff01&#39;<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">user<\/span><span class=\"o\">!<\/span><span class=\"p\">.<\/span><span class=\"nx\">board_count<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">throw<\/span> <span class=\"k\">new<\/span> <span class=\"nb\">Error<\/span><span class=\"p\">(<\/span><span class=\"s1\">&#39;\u7528\u6237\u6ca1\u6709\u753b\u677f\uff01&#39;<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kr\">const<\/span> <span class=\"nx\">user<\/span>: <span class=\"kt\">IUser<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">response<\/span><span class=\"p\">.<\/span><span class=\"nx\">user<\/span><span class=\"o\">!<\/span>\n    <span class=\"kr\">const<\/span> <span class=\"nx\">requestUserBoardsCount<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">user<\/span><span class=\"p\">.<\/span><span class=\"nx\">boards<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span>\n    <span class=\"nx\">allUserBoards<\/span><span class=\"p\">.<\/span><span class=\"nx\">push<\/span><span class=\"p\">(...<\/span><span class=\"nx\">user<\/span><span class=\"p\">.<\/span><span class=\"nx\">boards<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"c1\">\/\/ \u83b7\u53d6\u6240\u6709\u753b\u677f\u6570\u636e\n<\/span><span class=\"c1\"><\/span>    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">requestUserBoardsCount<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">allUserBoards<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">user<\/span><span class=\"p\">.<\/span><span class=\"nx\">board_count<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"k\">await<\/span> <span class=\"nx\">getBoards<\/span><span class=\"p\">(<\/span><span class=\"nx\">user<\/span><span class=\"p\">.<\/span><span class=\"nx\">boards<\/span><span class=\"p\">[<\/span><span class=\"nx\">requestUserBoardsCount<\/span> <span class=\"o\">-<\/span> <span class=\"mi\">1<\/span><span class=\"p\">].<\/span><span class=\"nx\">board_id<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">}<\/span>\n  <span class=\"p\">}<\/span>\n\n  <span class=\"k\">await<\/span> <span class=\"nx\">getBoards<\/span><span class=\"p\">()<\/span>\n  <span class=\"k\">return<\/span> <span class=\"nx\">allUserBoards<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre><\/td><\/tr><\/table>\n<\/div>\n<\/div><\/li>\n<li>\n<p>\u540e\u9762\u6b65\u9aa4\u8ddf\u65b9\u5f0f\u4e00\u76f8\u540c\uff0c\u8fd9\u91cc\u53ea\u662f\u4f7f\u7528 <code>for<\/code> \u5faa\u73af\u4e0b\u8f7d\u591a\u4e2a\u753b\u677f\u56fe\u7247<\/p>\n<\/li>\n<\/ol>\n<h2 id=\"\u603b\u7ed3\">\u603b\u7ed3<\/h2>\n<p>\u8fd9\u6b21\u722c\u866b\u51e0\u4e4e\u6ca1\u6709\u9047\u5230\u670d\u52a1\u5668\u7684\u53cd\u6297\uff0c\u82b1\u74e3\u7f51\u6ca1\u6709\u505a\u53cd\u722c\u866b\u68c0\u6d4b\uff0c\u6700\u57fa\u672c\u7684 <code>User-Agent<\/code> \u90fd\u4e0d\u9700\u8981\u4f2a\u88c5\uff0c\u5f88\u9002\u5408\u722c\u866b\u521d\u5b66\u8005\u62ff\u6765\u7ec3\u624b\uff1b\u8fd9\u79cd\u5f00\u653e\u5171\u4eab\u7684\u7cbe\u795e\u503c\u5f97\u8868\u626c\ud83d\udc4d\u3002<\/p>\n<p>\u9057\u7559\u4e0b\u4e86\u6709\u4e9b\u753b\u677f <code>pins<\/code> \u6570\u636e\u4e0d\u5168\u7684\u95ee\u9898\uff0c\u7b49\u5f85\u6709\u7f18\u518d\u89e3\u51b3\u3002<\/p>\n<h2 id=\"github-project\">Github Project<\/h2>\n<p>\u9879\u76ee\u5f15\u5165\u4e86 <code>TSLint<\/code>\u3001<code>Prettier<\/code> \u6765\u89c4\u8303\u4ee3\u7801\u98ce\u683c\uff0c\u7528 <code>ts-node<\/code> \u6765\u6267\u884c <code>.ts<\/code> \u7a0b\u5e8f\uff1b<\/p>\n<p>\u4ee3\u7801\u653e\u5230Github\u4e0a\u4e86 \u27a1 <a href=\"https:\/\/github.com\/Jancat\/huaban-crawl\">Jancat\/huaban-crawl<\/a><\/p>\n<p>Enjoy the pictures ~<\/p>"}]}}