添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

我的 promise function 沒有正常運作, 請問是甚麼原因呢?

function getImages(imageArray){
	return new Promise((resolve, reject) => {
		let array = [1, 2, 3];
		for (let i = 0; i < imageArray.length; i++) {
		    const reader = new FileReader();
		    reader.onload = function (e) {
		    	const img = new Image();
		    	img.onload = function(){
		    		if(img.width === 960 && img.height === 960){
		    			let imgSrc = e.target.result.split(",");
		    			if(imgSrc[0].indexOf("png") > -1 || imgSrc[0].indexOf("jpg") > -1 || imgSrc[0].indexOf("jpeg") > -1){
		    				const imageHTML = [];
		    				imageHTML.push(`<input type='checkbox' class='imagecheckbox noM' id='imagecheckbox' onclick='checkit()' value="${i}">`);
		    				array.push(imageHTML);
		    			} else {
		    				alert("只允許上傳JPG、或PNG影像檔");return;
		    		}else{
		    			alert("您所上傳圖片尺寸未符合規範");return;
		    	img.src = e.target.result;
		    reader.readAsDataURL(imageArray[i]);			    
		resolve(array);	
	getImages($("#imageUpload")[0].files)
		.then((success) => {
			console.log(success);  // 這裡還是回傳空陣列
  • 讀取檔案、讀取圖檔兩個步驟都是非同步,所以分別寫成兩個回傳 Promise 的函式方便串接
  • 針對陣列中的每個元素都要代入非同步的狀況,可以用 Promise.all。或是改用 async...await 用迴圈去跑也可以。
  • function getImages(imageArray) {
         * 讀取檔案為 dataurl
         * @param {File} file 檔案
         * @returns {Promise.<string>} promise of dataurl
        function readAsDataUrl(file) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                reader.onload = function (e) {
                    resolve(e.target.result);
                reader.readAsDataURL(file);
        function checkImage(dataurl) {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.onload = function () {
                    if (img.width === 960 && img.height === 960) {
                        let imgSrc = dataurl.split(",");
                        if (imgSrc[0].indexOf("png") > -1 || imgSrc[0].indexOf("jpg") > -1 || imgSrc[0].indexOf("jpeg") > -1) {
                            resolve(dataurl);
                        } else {
                            reject("只允許上傳JPG、或PNG影像檔");
                    } else {
                        reject("您所上傳圖片尺寸未符合規範");
                img.onerror = function () {
                    reject("只允許上傳JPG、或PNG影像檔");
                img.src = dataurl;
        return Promise.all(Array.from(imageArray).map(x => readAsDataUrl(x).then(checkImage)));
    $("#imageUpload").on('change', evt => {
        getImages(evt.target.files)
            .then((success) => {
                console.log(success.map((dataurl, i) => {
                    return `<input type='checkbox' class='imagecheckbox noM' id='imagecheckbox' onclick='checkit()' value="${i}">`;
            }).catch(error => {
                alert(error);
    
    async function getImages(imageArray) {
        let array = [];
        for (let i = 0; i < imageArray.length; i++) {
            let imageHTML = await new Promise((resolve, reject) => {
                const html = `<input type='checkbox' class='imagecheckbox noM' id='imagecheckbox' onclick='checkit()' value="${i}">`;
                const reader = new FileReader();
                reader.onload = function (e) {
                    const img = new Image();
                    img.onload = function () {
                        if (img.width === 960 && img.height === 960) {
                            let imgSrc = e.target.result.split(",");
                            if (imgSrc[0].indexOf("png") > -1 || imgSrc[0].indexOf("jpg") > -1 || imgSrc[0].indexOf("jpeg") > -1) {
                                resolve(html);
                            } else {
                                reject("只允許上傳JPG、或PNG影像檔");
                        } else {
                            reject("您所上傳圖片尺寸未符合規範");
                    img.onerror = function() {
                        reject("只允許上傳JPG、或PNG影像檔");
                    img.src = e.target.result;
                reader.readAsDataURL(imageArray[i]);
            array.push(imageHTML);
        return array;
    $("#imageUpload").on('change', evt => {
        getImages(evt.target.files)
            .then((success) => {
                console.log(success);
            }).catch(error => {
                alert(error);
    async function getImages(imageArray) {
        let array = [];
        for (let i = 0; i < imageArray.length; i++) {
            let imageHTML = await new Promise((resolve, reject) => {
                const html = `<input type='checkbox' class='imagecheckbox noM' id='imagecheckbox' onclick='checkit()' value="${i}">`;
                const reader = new FileReader();
                reader.onload = function (e) {
                    const img = new Image();
                    img.onload = function () {
                        if (img.width === 960 && img.height === 960) {
                            let imgSrc = e.target.result.split(",");
                            if (imgSrc[0].indexOf("png") > -1 || imgSrc[0].indexOf("jpg") > -1 || imgSrc[0].indexOf("jpeg") > -1) {
                                resolve(html);
                            } else {
                                reject("只允許上傳JPG、或PNG影像檔");
                        } else {
                            reject("您所上傳圖片尺寸未符合規範");
                    img.onerror = function() {
                        reject("只允許上傳JPG、或PNG影像檔");
                    img.src = e.target.result;
                reader.readAsDataURL(imageArray[i]);
            array.push(imageHTML);
        return array;
    $("#imageUpload").on('change', evt => {
        getImages(evt.target.files)
            .then((success) => {
                console.log(success);
            }).catch(error => {
                alert(error);
                                

    他沒有錯誤訊息,
    imageArray 的值是 <input id="imageUpload" type="file" draggable="true" accept="image/gif, image/jpeg, image/png" multiple="" onChange="selectImage()"> 的值

    本來沒有promise, 是在每次for loop傳一次資料出去, 反而能成功....