2017-08-10 106 views
1

我實際上正在開發一個文本編輯器,只是遇到了關於圖像上傳和顯示方法的問題。將承諾解析爲addEventListener

我試圖實現

在工具欄中點擊按鈕,應用程序會顯示一個彈出式的 上傳圖片。用戶可以拖放文件或點擊 並通過他的文件系統選擇文件。選中圖像 後,我通過ajax將其上傳到服務器,然後將其存儲在一個文件夾中。完成此操作後,服務器會發送一個響應 該文件可以正常使用。該功能然後解析並編輯器將正確的鏈接添加到圖像。

我嘗試了一些工作,同時在承諾中附加事件監聽器。

function uploadImage(editor) { 
 
    /* Displays the pop-up */ 
 
    uploadView.style.display = "block"; 
 

 
    var promise = new Promise(function(resolve, reject) { 
 

 
    uploadInput.addEventListener('change', function(event) { 
 
     /* ajax call */ 
 
     resolve(value); 
 
    }); 
 
    dropZone.addEventListener('drop', function(event) { 
 
     /* ajax call */ 
 
     resolve(value); 
 
    }); 
 

 
    }); 
 

 
    promise.then(function(result) { 
 
    /* Adds the link */ 
 
    }, function(err) { 
 
    /* handles errors */ 
 
    }); 
 
}

這一切都很好,但每次你觸發功能,新的偵聽器連接並在函數內部運行每股新點擊另一個時間...

我當時以爲我可能會在承諾解決後刪除監聽器。然而,爲了做到這一點,我不能使用匿名函數,但是我不能在裏面使用我的解決方法,因爲它會引發錯誤。

這不是工作:

function uploadImage(editor) { 
 
    /* Displays the pop-up */ 
 
    uploadView.style.display = "block"; 
 

 
    var promise = new Promise(function(resolve, reject) { 
 

 
    uploadInput.addEventListener('change', handleUpload); 
 
    dropZone.addEventListener('drop', handleUpload); 
 

 
    }); 
 

 
    promise.then(function(result) { 
 
    /* Adds the link */ 
 
    /* Removes the listeners */ 
 
    uploadInput.removeEventListener('change', handleUpload); 
 
    dropZone.removeEventListener('drop', handleUpload); 
 

 
    }, function(err) { 
 
    /* Handles errors */ 
 
    /* Removes the listeners */ 
 
    uploadInput.removeEventListener('change', handleUpload); 
 
    dropZone.removeEventListener('drop', handleUpload); 
 
    }); 
 
} 
 

 
function handleUpload(event) { 
 
    if (event.type == "change") { 
 
    /* ajax call */ 
 
    resolve(value); // Throws an error 
 
    } else { 
 
    /* ajax call */ 
 
    resolve(value); // Throws an error 
 
    } 
 
}
爲了做到這一點

我跑出來的想法......

回答

2

,我不能使用的匿名功能,但我不能使用我的解決方法裏面

沒有理由移動的功能(S)的uploadImage函數或命名或將它們轉換爲聲明時new Promise回調之外:

var promise = new Promise(function(resolve, reject) { 
    function handleUpload(event) { 
    /* Removes the listeners */ 
    uploadInput.removeEventListener('change', handleUpload); 
    dropZone.removeEventListener('drop', handleUpload); 
    resolve(event); // works just fine 
    } 
    uploadInput.addEventListener('change', handleUpload); 
    dropZone.addEventListener('drop', handleUpload); 
}); 

promise.then(function(event) { 
    if (event.type == "change") { 
    return /* ajax call */ 
    } else { 
    return /* other ajax call */ 
    } 
}).then(function(result) { 
    /* Adds the link */ 
}, function(err) { 
    /* Handles errors */ 
}); 
+0

在同一個承諾上鍊接多個.then()方法是否很常見?之前從未見過。我會試一試。 –

+0

運行順利!這次真是萬分感謝。 –

+0

@PierreBurton它沒有將它們鏈接到同一個'promise',它將它鏈接到由'promise.then(...)'(用ajax結果解析)返回的promise。是的,這很常見。 – Bergi

1

ElementTarget.addEventListener()有三個參數。事件名稱,回調和選項對象。現在這個選項對象很有趣,可以很方便,因爲它包含一個名爲once的布爾屬性。它有什麼作用..?

  • once:一個布爾值,指示偵聽器在添加後最多應調用一次。如果爲true,則在調用時將自動刪除偵聽器。

很酷。那麼你可以簡單地改變你的第一個片段如下:

function uploadImage(editor) { 
    /* Displays the pop-up */ 
    uploadView.style.display = "block"; 

    var promise = new Promise(function(resolve, reject) { 

    uploadInput.addEventListener('change', function(event) { 
     /* ajax call */ 
     resolve(value); 
    },{once: true}); // remove event after run once 
    dropZone.addEventListener('drop', function(event) { 
     /* ajax call */ 
     resolve(value); 
    },{once: true}); // remove event after run once 

    }); 

    promise.then(function(result) { 
    /* Adds the link */ 
    }, function(err) { 
    /* handles errors */ 
    }); 
} 
+1

聽起來很有趣。得看看這個! –