函數內賦值失效問題

来源:https://www.cnblogs.com/webwjg/archive/2020/06/12/13098861.html
-Advertisement-
Play Games

我用get向我的女神表白,可是她總是不理我,我絞盡腦汁,就是找不到原因,最後抱著試試的方法,就用post向女神表白,她馬上就同意了。我一直不明白這是為什麼? 有知道的可以評論下。還有,在這個前所未有的好日子,祝天下有情人今天都得加班。 我這個單身狗今天很閑(自由真舒服),就想改下之前的代碼,不改還好 ...


我用get向我的女神表白,可是她總是不理我,我絞盡腦汁,就是找不到原因,最後抱著試試的方法,就用post向女神表白,她馬上就同意了。我一直不明白這是為什麼?

有知道的可以評論下。還有,在這個前所未有的好日子,祝天下有情人今天都得加班。

我這個單身狗今天很閑(自由真舒服),就想改下之前的代碼,不改還好,一改出問題了,先上代碼:

function qrCodeNext(url,strHeader,canDom,imgDom){
	var BASE;
    var	qrText = url,//要生成二維碼的信息,文本或URL
        strFooter = '生成一個二維碼',//底部文字描述
        picWidth = 20,//圖片額外寬
        picHeight = 60,//圖片額外高
        fontSize = 14;//描述文字大小
    var qrcode=canDom.qrcode({
        render: 'canvas',
        text:qrText,
        width:200,
        height:190,
        background: '#ffffff',
        foreground: '#000000'
    });
    var canvas = canDom.find('canvas').get(0);
    var img=new Image();
    img.src=canvas.toDataURL('image/png');
    img.onload=function(){
        var w=img.width+20;
        var h=img.height+40;
        var ctx = canvas.getContext('2d');
        canvas.width = w;
        canvas.height = h;
            //設置畫布背景
        ctx.fillStyle = '#ffffff';
        ctx.fillRect(0,0, canvas.width, canvas.height);
            //設置文字樣式
        ctx.fillStyle = '#000000';
        ctx.font = 'bold 14px Arial';
        ctx.textAlign = 'center';
            //繪製頂部文字描述
        ctx.fillText(strHeader,w/2,60/3);  //文本 x坐標 y坐標
            //繪製二維碼
        ctx.drawImage(img,20/2,60/2);  //向畫布是繪製圖片
        var data=canvas.toDataURL('image/png',1);
        BASE=data;
            //顯示二維碼
        canvas=null;
        var imgCode=new Image();
        imgCode.src=data;
        imgDom.append(imgCode);

    };
    return BASE;

}

  

厲害的小伙伴應該都能看出來了,這是一段用qrCode生成帶文字二維碼的代碼,生成二維碼很順利,但是我今天就想能不能把生成的圖片的路徑return出去,問題就出在這了,我想著函數不能return那還叫函數嗎?對吧。可是,現實啪啪打臉。
我在qrCodeNext函數內聲明瞭一個變數BASE,然後在 img.onload中把canvas生成的圖片的路徑data賦給BASE,然後return出去,可是可是

這不是我忘了寫,這是空,這不但是空值,這更是大巴掌啊,呼呼的在抽我的臉。
這是為什麼呢?不廢話,開始找原因,
發現

 

 我發現在qrCodeNext函數內列印的就已經是空了,這意味著什麼,意味著在img.onload中,data並沒有賦值給BASE,但是在img.onload中列印的BASE卻是有值的

 

 現在我們要思考了,為什麼一個全局變數在函數內賦值成功了,外面確拿不到值呢?我想啊想,找啊找,阿哈,真相只有一個,那就是

 

 看明白了沒,明白了沒。真是就是你在列印值或者return BASE的時候,img.onload還沒有執行完成,所以你是先return,後賦值,當然是空了啊。
那怎麼解決呢?哈哈,很簡單啊,
你只要延遲一下就好了啊

 

 

用setTimeout延遲一下就能取到值了,要先執行下qrCodeNext函數才能列印,你也可以把BASE改為全局變數,就不用return也一樣可以拿到值。
還有一種更新的解決方法,建議大家用這個,就是使用ES6的promise,有興趣的可以去看看教程
代碼:

function qrCodeNext1(url,strHeader,canDom,imgDom){
    return new Promise(function (resolve,reject) {
        var    qrText = url,//要生成二維碼的信息,文本或URL
            strFooter = '生成一個二維碼',//底部文字描述
            picWidth = 20,//圖片額外寬
            picHeight = 60,//圖片額外高
            fontSize = 14;//描述文字大小
        var qrcode=canDom.qrcode({
            render: 'canvas',
            text:qrText,
            width:200,
            height:190,
            background: '#ffffff',
            foreground: '#000000'
        });
        var canvas = canDom.find('canvas').get(0);
        var img=new Image();
        img.src=canvas.toDataURL('image/png');
        img.onload=function(){
            var w=img.width+20;
            var h=img.height+40;
            var ctx = canvas.getContext('2d');
            canvas.width = w;
            canvas.height = h;
            //設置畫布背景
            ctx.fillStyle = '#ffffff';
            ctx.fillRect(0,0, canvas.width, canvas.height);
            //設置文字樣式
            ctx.fillStyle = '#000000';
            ctx.font = 'bold 14px Arial';
            ctx.textAlign = 'center';
            //繪製頂部文字描述
            ctx.fillText(strHeader,w/2,60/3);  //文本 x坐標 y坐標
            //繪製二維碼
            ctx.drawImage(img,20/2,60/2);  //向畫布是繪製圖片
            var data=canvas.toDataURL('image/png',1);

             // console.log(BASE); //我是值
             //顯示二維碼
            canvas=null;
                // var imgCode=new Image();
             //imgCode.src=data;
                // imgDom.append(imgCode);

            resolve(data)
        };

    });

}
//調用
qrCodeNext1(url,strHeader,canDom,imgDom).then(function (value) {
    console.log(value)  //data值
});

不要嫉妒我的智慧哦☺

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 摘要 平常生活中,地圖導航是必不可少的,最近在學習Ant Design,瞭解了下社區的精選組件,看到了與地圖相關的精品組件庫,高德地圖組件庫。所以記錄下這次高德地圖的使用心得,既可以提升自己的業務多樣性,也可以分享給需要的小伙伴。 React-Amap用法 安裝 npm install --save ...
  • 本文主要介紹如何通過CLI命令行(也就是終端或者cmd打開的那個shell視窗)實現 js和 css 的合併壓縮。 uglifyjs 合併壓縮 js: 1.安裝node 這一步就不多說了,下載node自行安裝。 2.安裝 uglifyjs 全局安裝: npm install -g uglify-js ...
  • 一. 普通對象與函數對象 JavaScript 中,萬物皆對象!但對象也是有區別的。分為普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。下麵舉例說明 var o1 = {}; var o2 =new Object(); var o3 = new f1(); ​ fun ...
  • # 從零開始的前端生活--盒尺寸 padding padding對塊級元素的影響 css中預設的box-sizing 是content-box,使用padding會額外增加元素的尺寸。 當padding足夠大,把width擠沒掉了,這時width就無效。裡面的內容表現為“首選最小寬度” 首選最小寬 ...
  • 最近碰到了關於閉包的問題,查看資料總結下我眼中的閉包 var price=document.getElementsByTagName('div'); for (var i = 0; i < 6; i++) { price[i].onClick=function () { console.log(i) ...
  • 1.創建github庫 創建github庫這個網上有很多教程,不是很難,不懂得可以搜下。 創建好庫之後我們把庫的地址複製下來 點擊圖中標註的地方就能把github庫的地址複製下來。 之後我們把庫clone到本地,我們需要新建一個文件夾,然後開始clone,克隆方式可以使用git也可以cmd(我的是w ...
  • 俗人手把手教你搭建vue項目 項目使用vue-cli開始,包含全家桶(vue-cli + vue3.0 + vuex + vue-router + axios + element-ui),包括自定義方法等。俗人會在本文中把詳細的流程呈現出來。 我把新建的項目放到我的庫里,有需要的可以自行c http ...
  • web前端開發由網頁製作演變而來,隨著web2.0的發展,網頁不再只是承載單一的文字和圖片,各種豐富媒體讓網頁的內容更加生動,網頁上軟體化的交互形式為用戶提供了更好的使用體驗,這些都是基於前端技術實現的。 經過了市場的沉澱,很多前端們開始無所適從,以前簡單的技能已經無法適用前端技術的發展,新技術新框 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...