promise怎麼取代程式碼中的回呼函數
這次帶給大家promise怎麼取代程式碼中的回呼函數,promise替代程式碼中回呼函數的注意事項有哪些,以下就是實戰案例,一起來看一下。
在學習 Node.js 過程中接觸到如何使用 async 來控制並發(使用 async 控制並發)
async 的本質是一個流程控制。其實在非同步程式設計中,還有一個更經典的模型,叫做Promise/Deferred 模型(當然還有更多相關解決方法,例如eventproxy,co 等,到時候遇到在挖坑)
#首先,我們思考一個典型的非同步程式設計模型,考慮這樣一個題目:讀取一個文件,在控制台輸出這個文件內容
var fs = require('fs'); fs.readFile('1.txt', 'utf8', function (err, data) { console.log(data); });
看起來很簡單,再進一步: 讀取兩個文件,在控制台輸出這兩個檔案內容
var fs = require('fs'); fs.readFile('1.txt', 'utf8', function (err, data) { console.log(data); fs.readFile('2.txt', 'utf8', function (err, data) { console.log(data); }); });
如果要是讀取更多的檔案呢
var fs = require('fs'); fs.readFile('1.txt', 'utf8', function (err, data) { fs.readFile('2.txt', 'utf8', function (err, data) { fs.readFile('3.txt', 'utf8', function (err, data) { fs.readFile('4.txt', 'utf8', function (err, data) { // ... }); }); }); });
這就是傳說中的callback hell,可以使用async 來改善這段程式碼,但在本例子中我們要用promise/defer 來改善它
promise 基本概念
首先它是一個對象,它和javascript 普通的對象沒什麼區別,同時,它也是一種規範,跟異步操作約定了統一的接口,表示一個異步操作的最終結果,以同步的方式來寫代碼,執行的操作是異步的,但又保證程式執行的順序是同步的
1. promise 只有三種狀態,未完成,完成(fulfilled) 和失敗(rejected)
2. promise 的狀態可以由未完成轉換成完成,或未完成轉換成失敗
3. promise 的狀態轉換只發生一次
promise 有一個then 方法,then 方法可以接受3 個函數作為參數。前兩個函數對應 promise 的兩種狀態 fulfilled, rejected 的回呼函數。第三個函數用來處理進度資訊
為了理解它,一些重要原理必須記牢:.then() 總是傳回一個新的promise,如下面程式碼:
var promise = readFile() var promise2 = promise.then(readAnotherFile, console.error)
這裡then 的參數readAnotherFile, console.error 是代表非同步操作成功後的動作onFulfilled 或失敗後的動作OnRejected,也就是說,讀取檔案成功後執行readAnotherFile 函數,否則失敗列印記錄錯誤。這個實作是兩個中只有一個可能
也可以理解為:
promiseSomething().then(function (fulfilled) { // 当 promise 状态变成 fulfilled 时,调用此函数 }, function (rejected) { // 当 promise 状态变成 rejected 时,调用此函数 }, function (progress) { // 当返回进度信息时,调用此函数 });
Promise 法則有兩個部分必須分離:
1. then() 總是返回一個新的promise,每次你調用它,它不管回調做什麼,因為.then() 在回調被調用之前已經給了你一個承諾promise,回調的行為只影響承諾promise 的實施,如果回調返回一個值,那麼promise 會使用那個值,如果這個值是promise,回傳這個promise 實作後的值給這個值,如果回呼拋出錯誤,promise 會拒絕錯誤
2. 被.then()回傳的promise 是一個新的promise ,它不同於那些.then() 被呼叫的promise,promise 長長的鏈條有時會好些隱藏這個事實,不管如何,每次.then() 呼叫都會產生一個新的promise ,這裡必須注意的是你真正需要考慮的是你最後調用.then() 可能代表失敗,那麼如果你不捕獲這種失敗,那麼容易導致你的錯誤exception 消失
來看一個利用q 來處理這種問題的簡單範例:
var Q = require('q'); var defer = Q.defer(); /** * 获取初始 promise * @private */ function getInitialPromise() { return defer.promise; } /** * 为 promise 设置三种状态的回调函数 */ getInitialPromise().then(function (success) { console.log(success); }, function (error) { console.log(error); }, function (progress) { console.log(progress); }); defer.notify('in progress'); // 控制台打印 in progress defer.resolve('resolve'); // 控制台打印 resolve defer.reject('reject'); // 没有输出。promise 的状态只能改变一次
promise 的傳遞
then 方法會傳回一個promise,在下面這個例子中,我們用outputPromise 指向then 回傳的promise。
var outputPromise = getInputPromise().then(function (fulfilled) { }, function (rejected) { });
現在 outputPromise 就變成了受 function(fulfilled) 或 function(rejected) 控制狀態的 promise 了。直白的意思是:當 function(fulfilled) 或 function(rejected) 傳回一個值,例如字串,陣列,物件等等,那麼 outputPromise 的狀態就會變成 fulfilled。
在下面這個例子中,我們可以看到,當我們把inputPromise 的狀態通過defer.resovle() 變成fulfilled 時,控制台輸出fulfilled.
#當我們把inputPromise 的狀態透過defer.reject() 變成rejected,控制台輸出rejected
var Q = require('q'); var defer = Q.defer(); /** * 通过 defer 获得 promise * @private */ function getInputPromise() { return defer.promise; } /** * 当 inputPromise 状态由未完成变成 fulfil 时,调用 function(fulfilled) * 当 inputPromise 状态由未完成变成 rejected 时,调用 function(rejected) * 将 then 返回的 promise 赋给 outputPromise * function(fulfilled) 和 function(rejected) 通过返回字符串将 outputPromise 的状态由 * 未完成改变为 fulfilled * @private */ var outputPromise = getInputPromise().then(function (fulfilled) { return 'fulfilled'; }, function (rejected) { return 'rejected'; }); /** * 当 outputPromise 状态由未完成变成 fulfil 时,调用 function(fulfilled),控制台打印 'fulfilled: fulfilled'。 * 当 outputPromise 状态由未完成变成 rejected, 调用 function(rejected), 控制台打印 'rejected: rejected'。 */ outputPromise.then(function (fulfilled) { console.log('fulfilled: ' + fulfilled); }, function (rejected) { console.log('rejected: ' + rejected); }); /** * 将 inputPromise 的状态由未完成变成 rejected */ defer.reject(); // 输出 fulfilled: rejected /** * 将 inputPromise 的状态由未完成变成 fulfilled */ //defer.resolve(); // 输出 fulfilled: fulfilled
当 function(fulfilled) 或者 function(rejected) 抛出异常时,那么 outputPromise 的状态就会变成 rejected
var Q = require('q'); var fs = require('fs'); var defer = Q.defer(); /** * 通过 defer 获得 promise * @private */ function getInputPromise() { return defer.promise; } /** * 当 inputPromise 状态由未完成变成 fulfil 时,调用 function(fulfilled) * 当 inputPromise 状态由未完成变成 rejected 时,调用 function(rejected) * 将 then 返回的 promise 赋给 outputPromise * function(fulfilled) 和 function(rejected) 通过抛出异常将 outputPromise 的状态由 * 未完成改变为 reject * @private */ var outputPromise = getInputPromise().then(function (fulfilled) { throw new Error('fulfilled'); }, function (rejected) { throw new Error('rejected'); }); /** * 当 outputPromise 状态由未完成变成 fulfil 时,调用 function(fulfilled)。 * 当 outputPromise 状态由未完成变成 rejected, 调用 function(rejected)。 */ outputPromise.then(function (fulfilled) { console.log('fulfilled: ' + fulfilled); }, function (rejected) { console.log('rejected: ' + rejected); }); /** * 将 inputPromise 的状态由未完成变成 rejected */ defer.reject(); // 控制台打印 rejected [Error:rejected] /** * 将 inputPromise 的状态由未完成变成 fulfilled */ //defer.resolve(); // 控制台打印 rejected [Error:fulfilled]
当 function(fulfilled) 或者 function(rejected) 返回一个 promise 时,outputPromise 就会成为这个新的 promise.
这样做的意义在于聚合结果 (Q.all),管理延时,异常恢复等等
比如说我们想要读取一个文件的内容,然后把这些内容打印出来。可能会写出这样的代码:
// 错误的写法 var outputPromise = getInputPromise().then(function (fulfilled) { fs.readFile('test.txt', 'utf8', function (err, data) { return data; }); });
然而这样写是错误的,因为 function(fulfilled) 并没有返回任何值。需要下面的方式:
var Q = require('q'); var fs = require('fs'); var defer = Q.defer(); /** * 通过 defer 获得promise * @private */ function getInputPromise() { return defer.promise; } /** * 当 inputPromise 状态由未完成变成 fulfil时,调用 function(fulfilled) * 当 inputPromise 状态由未完成变成 rejected时,调用 function(rejected) * 将 then 返回的 promise 赋给 outputPromise * function(fulfilled) 将新的 promise 赋给 outputPromise * 未完成改变为 reject * @private */ var outputPromise = getInputPromise().then(function (fulfilled) { var myDefer = Q.defer(); fs.readFile('test.txt', 'utf8', function (err, data) { if (!err && data) { myDefer.resolve(data); } }); return myDefer.promise; }, function (rejected) { throw new Error('rejected'); }); /** * 当 outputPromise 状态由未完成变成 fulfil 时,调用 function(fulfilled),控制台打印 test.txt 文件内容。 * */ outputPromise.then(function (fulfilled) { console.log(fulfilled); }, function (rejected) { console.log(rejected); }); /** * 将 inputPromise 的状态由未完成变成 rejected */ //defer.reject(); /** * 将 inputPromise 的状态由未完成变成 fulfilled */ defer.resolve(); // 控制台打印出 test.txt 的内容
方法传递
方法传递有些类似于 Java 中的 try 和 catch。当一个异常没有响应的捕获时,这个异常会接着往下传递
方法传递的含义是当一个状态没有响应的回调函数,就会沿着 then 往下找
没有提供 function(rejected)
var outputPromise = getInputPromise().then(function (fulfilled) { })
如果 inputPromise 的状态由未完成变成 rejected, 此时对 rejected 的处理会由 outputPromise 来完成
var Q = require('q'); var fs = require('fs'); var defer = Q.defer(); /** * 通过defer获得promise * @private */ function getInputPromise() { return defer.promise; } /** * 当 inputPromise 状态由未完成变成 fulfil 时,调用 function(fulfilled) * 当 inputPromise 状态由未完成变成 rejected 时,这个 rejected 会传向 outputPromise */ var outputPromise = getInputPromise().then(function (fulfilled) { return 'fulfilled' }); outputPromise.then(function (fulfilled) { console.log('fulfilled: ' + fulfilled); }, function (rejected) { console.log('rejected: ' + rejected); }); /** * 将 inputPromise 的状态由未完成变成 rejected */ defer.reject('inputpromise rejected'); // 控制台打印 rejected: inputpromise rejected /** * 将 inputPromise的状态由未完成变成fulfilled */ //defer.resolve();
没有提供 function(fulfilled)
var outputPromise = getInputPromise().then(null, function (rejected) { })
如果 inputPromise 的状态由未完成变成 fulfilled, 此时对 fulfil 的处理会由 outputPromise 来完成
var Q = require('q'); var fs = require('fs'); var defer = Q.defer(); /** * 通过defer获得promise * @private */ function getInputPromise() { return defer.promise; } /** * 当 inputPromise 状态由未完成变成 fulfil时,传递给 outputPromise * 当 inputPromise 状态由未完成变成 rejected时,调用 function(rejected) * function(fulfilled) 将新的 promise 赋给 outputPromise * 未完成改变为 reject * @private */ var outputPromise = getInputPromise().then(null, function (rejected) { return 'rejected'; }); outputPromise.then(function (fulfilled) { console.log('fulfilled: ' + fulfilled); }, function (rejected) { console.log('rejected: ' + rejected); }); /** * 将 inputPromise 的状态由未完成变成 rejected */ // defer.reject('inputpromise rejected'); /** * 将 inputPromise 的状态由未完成变成fulfilled */ defer.resolve('inputpromise fulfilled'); // 控制台打印fulfilled: inputpromise fulfilled
可以使用 fail(function(error)) 来专门针对错误处理,而不是使用 then(null,function(error))
var outputPromise = getInputPromise().fail(function (error) { })
看这个例子:
var Q = require('q'); var fs = require('fs'); var defer = Q.defer(); /** * 通过defer获得promise * @private */ function getInputPromise() { return defer.promise; } /** * 当 inputPromise 状态由未完成变成 fulfil 时,调用 then(function(fulfilled)) * 当 inputPromise 状态由未完成变成 rejected 时,调用 fail(function(error)) * function(fulfilled) 将新的 promise 赋给 outputPromise * 未完成改变为reject * @private */ var outputPromise = getInputPromise().then(function (fulfilled) { return fulfilled; }).fail(function (error) { console.log('fail: ' + error); }); /** * 将 inputPromise 的状态由未完成变成 rejected */ defer.reject('inputpromise rejected');// 控制台打印 fail: inputpromise rejected /** * 将 inputPromise 的状态由未完成变成 fulfilled */ //defer.resolve('inputpromise fulfilled');
可以使用 progress(function (progress)) 来专门针对进度信息进行处理,而不是使用 then(function (success) { }, function (error) { }, function (progress) { })
var Q = require('q'); var defer = Q.defer(); /** * 获取初始 promise * @private */ function getInitialPromise() { return defer.promise; } /** * 为 promise 设置 progress 信息处理函数 */ var outputPromise = getInitialPromise().then(function (success) { }).progress(function (progress) { console.log(progress); }); defer.notify(1); defer.notify(2); // 控制台打印 1,2
promise 链
promise 链提供了一种让函数顺序执行的方法
函数顺序执行是很重要的一个功能。比如知道用户名,需要根据用户名从数据库中找到相应的用户,然后将用户信息传给下一个函数进行处理
var Q = require('q'); var defer = Q.defer(); // 一个模拟数据库 var users = [{ 'name': 'andrew', 'passwd': 'password' }]; function getUsername() { return defer.promise; } function getUser(username) { var user; users.forEach(function (element) { if (element.name === username) { user = element; } }); return user; } // promise 链 getUsername().then(function (username) { return getUser(username); }).then(function (user) { console.log(user); }); defer.resolve('andrew');
我们通过两个 then 达到让函数顺序执行的目的。
then 的数量其实是没有限制的。当然,then 的数量过多,要手动把他们链接起来是很麻烦的。比如
foo(initialVal).then(bar).then(baz).then(qux)
这时我们需要用代码来动态制造 promise 链
var funcs = [foo, bar, baz, qux] var result = Q(initialVal) funcs.forEach(function (func) { result = result.then(func) }) return result
当然,我们可以再简洁一点
var funcs = [foo, bar, baz, qux] funcs.reduce(function (pre, current),Q(initialVal){ return pre.then(current) })
看一个具体的例子
function foo(result) { console.log(result); return result + result; } // 手动链接 Q('hello').then(foo).then(foo).then(foo); // 控制台输出: hello // hellohello // hellohellohello // 动态链接 var funcs = [foo, foo, foo]; var result = Q('hello'); funcs.forEach(function (func) { result = result.then(func); }); // 精简后的动态链接 funcs.reduce(function (prev, current) { return prev.then(current); }, Q('hello'));
对于 promise 链,最重要的是需要理解为什么这个链能够顺序执行。如果能够理解这点,那么以后自己写 promise 链可以说是轻车熟路啊
promise 组合
回到我们一开始读取文件内容的例子。如果现在让我们把它改写成 promise 链,是不是很简单呢?
var Q = require('q'), fs = require('fs'); function printFileContent(fileName) { return function () { var defer = Q.defer(); fs.readFile(fileName, 'utf8', function (err, data) { if (!err && data) { console.log(data); defer.resolve(); } }) return defer.promise; } } // 手动链接 printFileContent('sample01.txt')() .then(printFileContent('sample02.txt')) .then(printFileContent('sample03.txt')) .then(printFileContent('sample04.txt')); // 控制台顺序打印 sample01 到 sample04 的内容
很有成就感是不是。然而如果仔细分析,我们会发现为什么要他们顺序执行呢,如果他们能够并行执行不是更好吗? 我们只需要在他们都执行完成之后,得到他们的执行结果就可以了
我们可以通过 Q.all([promise1,promise2...]) 将多个 promise 组合成一个 promise 返回。 注意:
1. 当 all 里面所有的 promise 都 fulfil 时,Q.all 返回的 promise 状态变成 fulfil
2. 当任意一个 promise 被 reject 时,Q.all 返回的 promise 状态立即变成 reject
我们来把上面读取文件内容的例子改成并行执行吧
var Q = require('q'); var fs = require('fs'); /** *读取文件内容 *@private */ function printFileContent(fileName) { // Todo: 这段代码不够简洁。可以使用 Q.denodeify 来简化 var defer = Q.defer(); fs.readFile(fileName, 'utf8', function (err, data) { if (!err && data) { console.log(data); defer.resolve(fileName + ' success '); } else { defer.reject(fileName + ' fail '); } }) return defer.promise; } Q.all([printFileContent('sample01.txt'), printFileContent('sample02.txt'), printFileContent('sample03.txt'), printFileContent('sample04.txt')]) .then(function (success) { console.log(success); }); // 控制台打印各个文件内容 顺序不一定
现在知道 Q.all 会在任意一个 promise 进入 reject 状态后立即进入 reject 状态。如果我们需要等到所有的 promise 都发生状态后(有的 fulfil, 有的 reject),再转换 Q.all 的状态, 这时我们可以使用 Q.allSettled
var Q = require('q'), fs = require('fs'); /** *读取文件内容 *@private */ function printFileContent(fileName) { // Todo: 这段代码不够简洁。可以使用Q.denodeify来简化 var defer = Q.defer(); fs.readFile(fileName, 'utf8', function (err, data) { if (!err && data) { console.log(data); defer.resolve(fileName + ' success '); } else { defer.reject(fileName + ' fail '); } }) return defer.promise; } Q.allSettled([printFileContent('nosuchfile.txt'), printFileContent('sample02.txt'), printFileContent('sample03.txt'), printFileContent('sample04.txt')]) .then(function (results) { results.forEach( function (result) { console.log(result.state); } ); });
结束 promise 链
通常,对于一个 promise 链,有两种结束的方式。第一种方式是返回最后一个 promise
如 return foo().then(bar);
第二种方式就是通过 done 来结束 promise 链
如 foo().then(bar).done()
为什么需要通过 done 来结束一个 promise 链呢? 如果在我们的链中有错误没有被处理,那么在一个正确结束的 promise 链中,这个没被处理的错误会通过异常抛出
var Q = require('q'); function getPromise(msg, timeout, opt) { var defer = Q.defer(); setTimeout(function () { console.log(msg); if (opt) defer.reject(msg); else defer.resolve(msg); }, timeout); return defer.promise; } /** * 没有用 done() 结束的 promise 链 * 由于 getPromse('2',2000,'opt') 返回 rejected, getPromise('3',1000) 就没有执行 * 然后这个异常并没有任何提醒,是一个潜在的 bug */ getPromise('1', 3000) .then(function () { return getPromise('2', 2000, 'opt') }) .then(function () { return getPromise('3', 1000) }); /** * 用 done() 结束的 promise 链 * 有异常抛出 */ getPromise('1', 3000) .then(function () { return getPromise('2', 2000, 'opt') }) .then(function () { return getPromise('3', 1000) }) .done();
附录:一个 Promise 简单的应用(Node.js笔记(5)promise)
附:Promises/A+ 规范
promise 代表一个异步操作的最终结果。主要通过 promise 的 then 方法订阅其最终结果的处理回调函数,和订阅因某原因无法成功获取最终结果的处理回调函数。
更对详细见:Promises/A+
A 与 A+ 的不同点
A+ 规范通过术语 thenable 来区分 promise 对象
A+ 定义 onFulfilled/onRejectd 必须是作为函数来调用,而且调用过程必须是异步的
A+ 严格定义了 then 方法链式调用时,onFulfilled/onRejectd 的调用顺序
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是promise怎麼取代程式碼中的回呼函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

有的用戶在安裝設備的時候遇到了錯誤,提示錯誤代碼28,其實這主要是由於驅動程式的原因,我們只要解決win7驅動程式碼28的問題就可以了,下面就一起來看一下應該怎麼來操作吧。 win7驅動程式碼28怎麼辦:首先,我們需要點擊螢幕左下角的開始選單。接著,在彈出的選單中找到並點擊“控制面板”選項。這個選項通常位於選單的底部或附近。點擊後,系統會自動開啟控制面板介面。在控制面板中,我們可以進行各種系統設定和管理操作。這是懷舊大掃除關卡中的第一步,希望對大家有幫助。然後,我們需要繼續操作,進入系統和

藍屏代碼0x0000001怎麼辦藍屏錯誤是電腦系統或硬體出現問題時的一種警告機制,代碼0x0000001通常表示出現了硬體或驅動程式故障。當使用者在使用電腦時突然遇到藍色畫面錯誤,可能會感到驚慌失措。幸運的是,大多數藍色畫面錯誤都可以透過一些簡單的步驟來排除和處理。本文將為讀者介紹一些解決藍屏錯誤代碼0x0000001的方法。首先,當遇到藍色畫面錯誤時,我們可以嘗試重

win10系統是一款非常優秀的高智慧系統強大的智慧可以為使用者帶來最好的使用體驗,一般正常的情況下使用者的win10系統電腦都不會出現任何的問題!但在優秀的電腦也難免會出現各種故障最近一直有小伙伴們反應自己的win10系統遇到了頻繁藍屏的問題!今天小編就為大家帶來了win10電腦頻繁藍屏不同代碼的解決方法讓我們一起來看看吧。電腦頻繁藍屏而且每次代碼不一樣的解決辦法:造成各種故障碼的原因以及解決建議1、0×000000116故障原因:應該是顯示卡驅動不相容。解決建議:建議更換廠商原帶驅動。 2、

終止代碼0xc000007b在使用電腦時,有時會遇到各種各樣的問題和錯誤代碼。其中,終止代碼最為令人困擾,尤其是終止代碼0xc000007b。這個程式碼表示某個應用程式無法正常啟動,給用戶帶來了不便。首先,我們來了解終止碼0xc000007b的意思。這個程式碼是Windows作業系統的錯誤代碼,通常發生在32位元應用程式嘗試在64位元作業系統上執行時。它表示應

如果您需要遠端編程任何設備,這篇文章會為您帶來幫助。我們將分享編程任何設備的頂級GE通用遠端代碼。通用電氣的遙控器是什麼? GEUniversalRemote是一款遙控器,可用於控制多個設備,如智慧電視、LG、Vizio、索尼、藍光、DVD、DVR、Roku、AppleTV、串流媒體播放器等。 GEUniversal遙控器有各種型號,具有不同的功能和功能。 GEUniversalRemote最多可以控制四台設備。頂級通用遙控器代碼,可在任何裝置上編程GE遙控器配備一組代碼,使其能夠與不同設備配合。您可

藍屏是我們在系統使用的時候常常會碰到的問題,根據錯誤代碼的不同,會有很多中不一樣的原因和解決方法。例如我們在使用時遇到stop:0x0000007f的問題,可能是硬體或軟體錯誤,下面就跟著小編一起來看看解決方法吧。 0x000000c5藍色畫面代碼原因:答:記憶體、CPU、顯示卡突然超頻,或軟體運作錯誤。解決方法一:1.開機時不斷按F8進入,選擇安全模式,回車進入。 2.進入安全模式後,按win+r開啟運行窗口,輸入cmd,回車。 3.在指令提示窗口,輸入“chkdsk/f/r”,回車,然後按y鍵。 4、

0x000000d1藍屏程式碼是什麼意思近年來,隨著電腦的普及和網路的快速發展,作業系統的穩定性和安全性問題也日益凸顯。一個常見的問題是藍色畫面錯誤,代碼0x000000d1是其中之一。藍色畫面錯誤,或稱為“藍色畫面死機”,是當電腦遇到嚴重系統故障時發生的情況。當系統無法從錯誤中恢復時,Windows作業系統會顯示一個藍色的螢幕,並在螢幕上顯示錯誤代碼。這些錯誤代

快速上手Python繪圖:畫出冰墩墩的程式碼範例Python是一種簡單易學且功能強大的程式語言,透過使用Python的繪圖庫,我們可以輕鬆實現各種繪圖需求。在本篇文章中,我們將使用Python的繪圖庫matplotlib來畫出冰墩墩的簡單圖形。冰墩墩是一隻擁有可愛形象的熊貓,非常受小朋友的喜愛。首先,我們需要安裝matplotlib函式庫。你可以透過在終端運行
