整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          CDR怎么繪制簡筆畫效果的葉子?CDR樹葉的繪制方法

          CDR怎么繪制簡筆畫效果的葉子?CDR樹葉的繪制方法

          dr怎么繪制簡筆畫效果的葉子?cdr中想要繪制一個簡單的樹葉效果,該怎么繪制呢?下面我們就來看看cdr樹葉的繪制方法,需要的朋友可以參考下:

          1、首先繪制一個圓,Ctrl+q轉曲。

          2、用形狀工具雙擊刪除左右連個節點。

          3、將上下兩個節點改為“尖突”。

          4、調整為如圖形狀,不必太工整對稱,因為要有手繪的自然和隨意感。

          5、將其復制一份,變形(向中間壓縮),放在中間,做成葉子紋理線條。

          6、按f12將“角”的類型改為第二個。

          7、用手繪工具繪制一條曲線,將葉片放在頂端,調整合適的方向。

          8、如是復制多個,排列在兩邊。完成。

          9、拓展一下,類似的方法,我們可以做出各種各樣的葉片和造型。大家盡可能的發揮想象。

          以上就是cdr樹葉的繪制方法,希望大家喜歡,軟件下載:http://www.coreldrawchina.com/xiazai.html。

          鳥網作者:落v葉

          出自蜂鳥網-人像攝影,原貼鏈接:https://m.fengniao.com/thread/11004426.html

          攝影/落葉

          模特/熙

          地點/桂林

          歡迎關注 蜂鳥網微信公眾號:fengniaoweixin

          vent Loop 是一個很重要的概念,指的是計算機系統的一種運行機制。

          JavaScript語言就采用這種機制,來解決單線程運行帶來的一些問題。

          想要理解Event Loop,就要從程序的運行模式講起。運行以后的程序叫做“進程”(process),一般情況下,一個進程一次只能執行一個任務。

          如果有很多任務需要執行,不外乎三種解決方法。

          (1)排隊。因為一個進程一次只能執行一個任務,只好等前面的任務執行完了,再執行后面的任務。

          (2)新建進程。使用fork命令,為每個任務新建一個進程。

          (3)新建線程。因為進程太耗費資源,所以如今的程序往往允許一個進程包含多個線程,由線程去完成任務。(進程和線程的詳細解釋,請看這里。)

          以JavaScript語言為例,它是一種單線程語言,所有任務都在一個線程上完成,即采用上面的第一種方法。一旦遇到大量任務或者遇到一個耗時的任務,網頁就會出現”假死”,因為JavaScript停不下來,也就無法響應用戶的行為。

          你也許會問,JavaScript為什么是單線程,難道不能實現為多線程嗎?

          這跟歷史有關系。JavaScript從誕生起就是單線程。原因大概是不想讓瀏覽器變得太復雜,因為多線程需要共享資源、且有可能修改彼此的運行結果,對于一種網頁腳本語言來說,這就太復雜了。后來就約定俗成,JavaScript為一種單線程語言。(Worker API可以實現多線程,但是JavaScript本身始終是單線程的。)

          如果某個任務很耗時,比如涉及很多I/O(輸入/輸出)操作,那么線程的運行大概是下面的樣子。

          上圖的綠色部分是程序的運行時間,紅色部分是等待時間??梢钥吹?,由于I/O操作很慢,所以這個線程的大部分運行時間都在空等I/O操作的返回結果。這種運行方式稱為”同步模式”(synchronous I/O)或”堵塞模式”(blocking I/O)。

          如果采用多線程,同時運行多個任務,那很可能就是下面這樣。

          上圖表明,多線程不僅占用多倍的系統資源,也閑置多倍的資源,這顯然不合理。

          Event Loop就是為了解決這個問題而提出的。Wikipedia這樣定義:

          “Event Loop是一個程序結構,用于等待和發送消息和事件。(a programming construct that waits for and dispatches events or messages in a program.)”

          簡單說,就是在程序中設置兩個線程:一個負責程序本身的運行,稱為”主線程”;另一個負責主線程與其他進程(主要是各種I/O操作)的通信,被稱為”Event Loop線程”(可以譯為”消息線程”)。

          上圖主線程的綠色部分,還是表示運行時間,而橙色部分表示空閑時間。每當遇到I/O的時候,主線程就讓Event Loop線程去通知相應的I/O程序,然后接著往后運行,所以不存在紅色的等待時間。等到I/O程序完成操作,Event Loop線程再把結果返回主線程。主線程就調用事先設定的回調函數,完成整個任務。

          可以看到,由于多出了橙色的空閑時間,所以主線程得以運行更多的任務,這就提高了效率。這種運行方式稱為”異步模式“(asynchronous I/O)或”非堵塞模式”(non-blocking mode)。

          這正是JavaScript語言的運行方式。單線程模型雖然對JavaScript構成了很大的限制,但也因此使它具備了其他語言不具備的優勢。如果部署得好,JavaScript程序是不會出現堵塞的,這就是為什么node.js平臺可以用很少的資源,應付大流量訪問的原因。

          以上是關于Event loop的概念,然而實際上的操作中我們會遇到非常多的問題,讓我們無從下手,在這里我給大家介紹一個自己的qun,里面有很多熱情的大神,更有實際操作過的老手和老師,我也會不時分享學習的資料和視頻(2131 26486),填寫并私聊我(落葉)直接領取。

          在實際工作中,了解Event loop的意義能幫助你分析一些異步次序的問題(當然,隨著es7 async和await的流行,這樣的機會越來越少了)。除此以外,它還對你了解瀏覽器和Node的內部機制有積極的作用;對于參加面試,被問到一堆異步操作的執行順序時,也不至于兩眼抓瞎。

          3. 瀏覽器上的實現

          在JavaScript中,任務被分為Task(又稱為MacroTask,宏任務)和MicroTask(微任務)兩種。它們分別包含以下內容:

          MacroTask: script(整體代碼), setTimeout, setInterval, setImmediate(node獨有), I/O, UI rendering

          MicroTask: process.nextTick(node獨有), Promises, Object.observe(廢棄), MutationObserver

          需要注意的一點是:在同一個上下文中,總的執行順序為同步代碼—>microTask—>macroTask[6]。這一塊我們在下文中會講。

          瀏覽器中,一個事件循環里有很多個來自不同任務源的任務隊列(task queues),每一個任務隊列里的任務是嚴格按照先進先出的順序執行的。但是,因為瀏覽器自己調度的關系,不同任務隊列的任務的執行順序是不確定的。

          具體來說,瀏覽器會不斷從task隊列中按順序取task執行,每執行完一個task都會檢查microtask隊列是否為空(執行完一個task的具體標志是函數執行棧為空),如果不為空則會一次性執行完所有microtask。然后再進入下一個循環去task隊列中取下一個task執行,以此類推。

          注意:圖中橙色的MacroTask任務隊列也應該是在不斷被切換著的。

          本段大批量引用了《什么是瀏覽器的事件循環(Event Loop)》的相關內容,想看更加詳細的描述可以自行取用。

          4. Node上的實現

          nodejs的event loop分為6個階段,它們會按照順序反復運行,分別如下:

          1. timers:執行setTimeout() 和 setInterval()中到期的callback。

          2. I/O callbacks:上一輪循環中有少數的I/Ocallback會被延遲到這一輪的這一階段執行

          3. idle, prepare:隊列的移動,僅內部使用

          4. poll:最為重要的階段,執行I/O callback,在適當的條件下會阻塞在這個階段

          5. check:執行setImmediate的callback

          6. close callbacks:執行close事件的callback,例如socket.on("close",func)

          不同于瀏覽器的是,在每個階段完成后,而不是MacroTask任務完成后,microTask隊列就會被執行。這就導致了同樣的代碼在不同的上下文環境下會出現不同的結果。我們在下文中會探討。

          另外需要注意的是,如果在timers階段執行時創建了setImmediate則會在此輪循環的check階段執行,如果在timers階段創建了setTimeout,由于timers已取出完畢,則會進入下輪循環,check階段創建timers任務同理。

          5. 示例

          5.1 瀏覽器與Node執行順序的區別

          setTimeout(()=>{ console.log('timer1') Promise.resolve().then(function() { console.log('promise1')
           })
          }, 0)
          setTimeout(()=>{ console.log('timer2') Promise.resolve().then(function() { console.log('promise2')
           })
          }, 0)
          瀏覽器輸出:
          time1
          promise1
          time2
          promise2
          Node輸出:
          time1
          time2
          promise1
          promise2

          在這個例子中,Node的邏輯如下:

          最初timer1和timer2就在timers階段中。開始時首先進入timers階段,執行timer1的回調函數,打印timer1,并將promise1.then回調放入microtask隊列,同樣的步驟執行timer2,打印timer2;

          至此,timer階段執行結束,event loop進入下一個階段之前,執行microtask隊列的所有任務,依次打印promise1、promise2。

          而瀏覽器則因為兩個setTimeout作為兩個MacroTask, 所以先輸出timer1, promise1,再輸出timer2,promise2。

          更加詳細的信息可以查閱《深入理解js事件循環機制(Node.js篇)》

          為了證明我們的理論,把代碼改成下面的樣子:

          setImmediate(()=> { console.log('timer1') Promise.resolve().then(function () { console.log('promise1')
           })
          })
          setTimeout(()=> { console.log('timer2') Promise.resolve().then(function () { console.log('promise2')
           })
          }, 0)
          Node輸出:
          timer1 timer2
          promise1 或者 promise2
          timer2 timer1
          promise2 promise1

          按理說

          setTimeout(fn,0)

          應該比

          setImmediate(fn)

          快,應該只有第二種結果,為什么會出現兩種結果呢?

          這是因為Node 做不到0毫秒,最少也需要1毫秒。實際執行的時候,進入事件循環以后,有可能到了1毫秒,也可能還沒到1毫秒,取決于系統當時的狀況。如果沒到1毫秒,那么 timers 階段就會跳過,進入 check 階段,先執行setImmediate的回調函數。

          另外,如果已經過了Timer階段,那么setImmediate會比setTimeout更快,例如:

          const fs=require('fs');
          fs.readFile('test.js', ()=> {
           setTimeout(()=> console.log(1));
           setImmediate(()=> console.log(2));
          });

          上面代碼會先進入 I/O callbacks 階段,然后是 check 階段,最后才是 timers 階段。因此,setImmediate才會早于setTimeout執行。

          具體可以看《Node 定時器詳解》。

          5.2 不同異步任務執行的快慢

          setTimeout(()=> console.log(1));
          setImmediate(()=> console.log(2));
          Promise.resolve().then(()=> console.log(3));
          process.nextTick(()=> console.log(4));
          輸出結果:4 3 1 2或者4 3 1 2

          因為我們上文說過microTask會優于macroTask運行,所以先輸出下面兩個,而在Node中process.nextTick比Promise更加優先[3],所以4在3前。而根據我們之前所說的Node沒有絕對意義上的0ms,所以1,2的順序不固定。

          5.3 MicroTask隊列與MacroTask隊列

           setTimeout(function () { console.log(1);
           },0); console.log(2);
           process.nextTick(()=> { console.log(3);
           }); new Promise(function (resolve, rejected) { console.log(4);
           resolve()
           }).then(res=>{ console.log(5);
           })
           setImmediate(function () { console.log(6)
           }) console.log('end');
          Node輸出:2 4 end 5 1 6

          這個例子來源于《JavaScript中的執行機制》。Promise的代碼是同步代碼,then和catch才是異步的,所以4要同步輸出,然后Promise的then位于microTask中,優于其他位于macroTask隊列中的任務,所以5會優于1,6輸出,而Timer優于Check階段,所以1,6。

          綜上,關于最關鍵的順序,我們要依據以下幾條規則:

          1. 同一個上下文下,MicroTask會比MacroTask先運行

          2. 然后瀏覽器按照一個MacroTask任務,所有MicroTask的順序運行,Node按照六個階段的順序運行,并在每個階段后面都會運行MicroTask隊列

          同個MicroTask隊列下process.tick()會優于Promise


          主站蜘蛛池模板: 国产99久久精品一区二区| 无码日韩精品一区二区免费| 亚洲一区二区三区高清在线观看 | 亚洲一区日韩高清中文字幕亚洲| 亚洲一区二区三区在线网站 | 无码播放一区二区三区| 97久久精品午夜一区二区| 日韩aⅴ人妻无码一区二区| 国产精品特级毛片一区二区三区| 国产精品电影一区二区三区| 国产精品亚洲午夜一区二区三区| 无码日韩精品一区二区三区免费| 精品国产AⅤ一区二区三区4区| 国产一区二区三区免费视频| 国产日产久久高清欧美一区| 精品动漫一区二区无遮挡| 亚洲一区二区三区91| 久久精品一区二区三区四区| 亚洲AV无码一区二区三区系列 | AA区一区二区三无码精片 | 国产A∨国片精品一区二区| 麻豆视频一区二区三区| 国产在线一区观看| 痴汉中文字幕视频一区| 一区二区三区免费在线观看| 精品视频一区二区三区四区五区| 全国精品一区二区在线观看| 亚洲AV日韩精品一区二区三区| 国产精品女同一区二区久久 | 欧美日韩一区二区成人午夜电影| 亚洲AV无码一区二区一二区| 成人免费一区二区无码视频| 免费精品一区二区三区在线观看| 在线视频精品一区| 亚洲国产激情一区二区三区| 国产在线不卡一区二区三区| 人妻无码第一区二区三区| 国产对白精品刺激一区二区| 丰满爆乳无码一区二区三区| 国产午夜一区二区在线观看| 熟女少妇精品一区二区|