我有一个回调,它等待HTTP请求的响应,如果文件成功上传,该响应将用单词“ done”响应,并且我通过回调发出一个请求,每次都上传一个文件。
我想要的是,当响应“完成”时,我想使用do-while
循环上传多个文件,并且我正在考虑使用promises进行操作,但是我真的不知道如何做。
现在我的代码:
var self = this;
let i = 0;
let fileInput = fileCmp.get("v.files");
do {
// my callback
self.uploadHelper(component, event, fileInput[i]);
console.log("Uploading: " + fileInput[i].name);
i++;
} while (i < fileInput.length);
我想要做的是仅当我收到响应“完成”或呼叫中的其他内容时转到i=1
(第二个文件)。
从uploadHelper()
调用的我的回调:
uploadChunk: function (component, file, fileContents, fromPos, toPos, attachId) {
console.log('uploadChunk');
var action = component.get("c.saveTheChunk");
var chunk = fileContents.substring(fromPos, toPos);
action.setParams({
parentId: component.get("v.recordId"),
fileName: file.name,
base64Data: encodeURIComponent(chunk),
contentType: file.type,
fileId: attachId
});
action.setCallback(this, function (a) {
console.log('uploadChunk: Callback');
attachId = a.getReturnValue();
fromPos = toPos;
toPos = Math.min(fileContents.length, fromPos + this.CHUNK_SIZE);
if (fromPos < toPos) {
this.uploadChunk(component, file, fileContents, fromPos, toPos, attachId);
} else {
console.log('uploadChunk: done');
component.set("v.showLoadingSpinner", false);
// enabling the next button
component.set("v.nextDisabled", false);
component.set("v.uploadDisabled", true);
component.set("v.clearDisabled", true);
component.set("v.showToast", true);
component.set("v.toastType", 'success');
component.set("v.fileName", '');
component.set("v.toastMessage", 'Upload Successful.');
}
});
$A.getCallback(function () {
$A.enqueueAction(action);
})();
}
答案 0 :(得分:0)
您必须使自己的uploadHelper
方法不具有异步性才能实现所需的功能。
尝试使用async
,await
和Promise
对象在函数中创建一个Promis(而不是回调),并强制其同步发生。
可能看起来像这样:
// uploadHelper definiton, fit its to your code
const uploadHelper = (component, event, file) => {
// Create the promise
return new Promise(function(component, event, file) {
// Do what you want to do
})
}
// Use it
var self = this;
let i = 0;
let fileInput = fileCmp.get("v.files");
do{
await self.uploadHelper(component, event, fileInput[i]).then(function() {
console.log("Uploading: "+fileInput[i].name);
i++;
});
}
while(i< fileInput.length);
有关更多信息,请尝试以下链接: https://developer.mozilla.org/he/docs/Web/JavaScript/Reference/Global_Objects/Promise https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
答案 1 :(得分:0)
当您的uploadChunk
执行异步任务时,该函数采取回调是有意义的,当任务完成时该回调将被回调(您的代码尚不包含任何回调)。由于回调难以处理(尤其是使用循环),因此将回调包装成Promise(在调用回调时解决)是很有意义的:
uploadChunk: function (component, file, fileContents, fromPos, toPos, attachId) {
return new Promise(resolve => { // the promise gets returned immeadiately, the "resolve" callback can be called to resolve it
// ....
action.setCallback(this, function (a) {
//...
resolve();
});
});
},
您的uploadHelper
现在可以将返回的承诺返回到循环中:
uploadHelper(component, event, file) {
//...
return this.uploadChunk(component, file, /*...*/);
}
现在我们有了这个,我们可以简单地await
在async
函数内部承诺:
(async () => { // arrow function to preserve "this"
for(const file of files) { // Why do...while if you can use a for..of?
await this.uploadChunk(component, event, file);
}
})();
答案 2 :(得分:-1)
摆脱while
循环,并在每次使用pop
数组时只需fileInput
即可。当数组为空时,取消所有操作。
(尽管您需要拥有一个有效的回调函数...)
答案 3 :(得分:-1)
嘿,您可以使用自动运行功能:
var self = this;
let i = 0;
let fileInput = fileCmp.get("v.files");
do{
// my callback
(()=>{
self.uploadHelper(component, event, fileInput[i]);
console.log("Uploading: "+fileInput[i].name);
i++;
})();
}
while(i< fileInput.length);