Javascript 如何使用Web Worker加速文件传输
我尝试将视频文件传输到名为“INFURA”的公共服务器Javascript 如何使用Web Worker加速文件传输,javascript,web-worker,data-transfer,Javascript,Web Worker,Data Transfer,我尝试将视频文件传输到名为“INFURA”的公共服务器 但是比我想象的要慢。(关于您是否认为问题在于您的CPU无法计算要发送的数据?您的CPU在这里几乎没有任何作用。罪魁祸首是在网络中。您的服务器或ISP的带宽将是限制设置者。我真诚地怀疑并行请求是否会加快速度。请注意,请求不是在与你的js相同的线程,如果你不事先对数据进行任何处理,你将不会从工作人员那里获得任何好处。@Kaido非常感谢你的回复。因为我的英语很差,我不确定你的意思是低速不是与web工作人员无关,只是与带宽有关。那么,我可以尝试解
但是比我想象的要慢。(关于您是否认为问题在于您的CPU无法计算要发送的数据?您的CPU在这里几乎没有任何作用。罪魁祸首是在网络中。您的服务器或ISP的带宽将是限制设置者。我真诚地怀疑并行请求是否会加快速度。请注意,请求不是在与你的js相同的线程,如果你不事先对数据进行任何处理,你将不会从工作人员那里获得任何好处。@Kaido非常感谢你的回复。因为我的英语很差,我不确定你的意思是低速不是与web工作人员无关,只是与带宽有关。那么,我可以尝试解决这个问题吗?这确实是我想要的我的意思是,虽然我必须承认,我不知道是否有解决方案可以加快速度,但我怀疑将您的请求分块是其中之一,而且我很确定员工不会这样做。@kaido谢谢您,非常感谢您。这真的很有帮助,因为我还没有阅读完整的代码,但有几点您需要知道。一:我明白了这是对浏览器中活动连接数量的限制,创建超过此限制的上载流是毫无意义的。就此而言,创建多个上载流是毫无意义的。第二:上载原始二进制数据使用很少的CPU,使用辅助线程几乎没有什么好处。第三:不能100%保证每个辅助线程都是真正的系统线程,o只知道它们会被彼此沙盒。此外,即使它们是真正的操作系统线程,每个CPU核心超过1个也没有意义。你是否认为问题在于你的CPU无法计算要发送的数据?你的CPU在这里几乎没有任何事可做。罪魁祸首是网络。你的服务器或ISP的带宽w我将是限制设定者。我真诚地怀疑并行请求是否会使任何事情更快。请注意,请求不是在与js相同的线程上进行的,如果您不在手头上对数据进行任何处理,您将不会从工作人员那里获得任何好处。@Kaido非常感谢您的回复。因为我的英语很差,我不确定你的意思是,低速度与网络工作者无关,而与带宽有关。那么,我是否可以尝试解决这一问题?这确实是我要说的,虽然我必须承认,我不知道是否有解决方案可以加快速度,但我怀疑将你的请求分块是其中之一,我非常确定工作者不会uch。这对meI来说真的很有帮助,因为她还没有读到完整的代码,但有几点你需要知道。第一:浏览器中活动连接的数量有限制,创建比这个限制更多的上传流是没有意义的。就这一点而言,创建多个上传流是没有意义的。第二:上传原始二进制数据使用很少第三:不能100%保证每个工作线程都是一个真正的系统线程,只能保证它们彼此之间是沙盒。此外,即使它们是真正的操作系统线程,每个CPU核的收益也没有意义。
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<!-- loading the minified version -->
<script src="https://unpkg.com/ipfs/dist/index.min.js"></script>
<script src="https://unpkg.com/ipfs-http-client/dist/index.min.js"></script>
<script src="https://unpkg.com/ipfs-api@9.0.0/dist/index.js" integrity="sha384-5bXRcW9kyxxnSMbOoHzraqa7Z0PQWIao+cgeg327zit1hz5LZCEbIMx/LWKPReuB" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/9.0.0/bignumber.js" integrity="sha256-TYZ2kR74G+TqMIiLuKpB57VUTNKhGFknyOKgRYqxhnw=" crossorigin="anonymous"></script>
</head>
<body>
<h1 id="title">IPFS Client TEST (Infura)</h1>
<select id="ipfs_client">
<option value="infura" selected="selected">infura</option>
<option value="private_gateway">private gateway</option>
</select>
<select id="num_of_chunks">
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
<div id="" style="margin-top:40px">
<h2>file upload</h2>
<input type="file" id="file" onchange="loadFile(event)" />
<input type="button" value="upload" id="send_ipfs" onclick="javascript:sendIpfs();" />
<input type="button" value="upload_webworker" id="send_ipfs_webworker" onclick="javascript:sendIpfsWebWorker();" />
<a id="file_url"></a>
</div>
<div id="" style="margin-top:40px">
<h2> file download </h2>
<input type="text" id="downloadHash" placeholder="download hash" onchange="" />
<input type="button" value="get" id="get_ipfs" onclick="javascript:getIpfs();" />
<a id="linkToDownload" href="" download=""></a>
</div>
<div style="margin-top:80px">
<h1>IPFS Node TEST (js-ipfs Node)</h1>
<div id="" style="margin-top:40px">
<h2>upload(browser Node) </h2>
<input type="file" id="fileBrowserNode" onchange="loadFileForBrowserNode(event)" />
<input type="button" value="upload" id="send_ipfs_to_browser_node" onclick="javascript:sendIpfsToBrowserNode()" />
<a id="file_url"></a>
</div>
<div id="" style="margin-top:40px">
<h2> download(browser Node) </h2>
<input type="text" id="downloadHashBrowserNode" placeholder="download hash" onchange="" />
<input type="button" value="get" id="get_ipfs_from_browser_node" onclick="javascript:getIpfsFromBrowserNode()" />
<a id="linkToDownloadBrowserNode" href="" download=""></a>
</div>
<div id="" style="margin-top:40px">
<h2> stat bandwidth </h2>
TotalIn:<span id="bwTotalIn"></span><br>
TotalOut:<span id="bwTotalOut"></span><br>
RateIn:<span id="bwRateIn"></span><br>
RateOut:<span id="bwRateOut"></span><br>
</div>
<div id="web_worker_test" style="margin-top:40px">
<h2> Webworker Test </h2>
ouput: <span id="web_worker_output"></span>
<button id="worker_run" value="run">run</button>
</div>
</div>
</body>
<script>
var downloadedfiles
var onloadfile
var numOfChunks = 0;
var uploadBuf = new Array(numOfChunks);
var downloadBuf = new Array(numOfChunks);
var fullLength
var ipfs = new Array(numOfChunks)
var uploadedChunkCnt = 0
var hashBuffer = new Array(numOfChunks)
var worker = new Array();
var uploadStartTime
$(document).ready(function() {
numOfChunks = $('#num_of_chunks').val()
chooseClient = function() {
var selectedClient = $('#ipfs_client').val();
console.log(selectedClient);
if (selectedClient == 'infura') {
for (var i = 0; i < numOfChunks; i++) {
ipfs[i] = window.IpfsHttpClient({
host: 'ipfs.infura.io',
port: 5001,
protocol: 'https'
});
}
$('#title').html('IPFS Client TEST (Infura)');
} else if (selectedClient == 'private_gateway') {
ipfs = window.IpfsHttpClient({
host: 'devipfs.nemodax.com',
port: 5001,
protocol: 'https'
})
$('#title').html('IPFS Client TEST (devipfs Private Gateway)');
}
}
function init() {
numOfChunks = $('#num_of_chunks').val()
worker = new Array()
if (typeof(onloadfile) != 'undefined') {
fullLength = onloadfile.result.byteLength;
chunkLength = fullLength / numOfChunks
for (var i = 0; i < numOfChunks; i++) {
var chunk
if (i == numOfChunks - 1) { // last chunk process
chunk = onloadfile.result.slice(i * chunkLength, fullLength)
} else {
chunk = onloadfile.result.slice(i * chunkLength, (i + 1) * chunkLength)
}
uploadBuf[i] = Ipfs.Buffer(chunk)
}
}
for (var i = 0; i < numOfChunks; i++) {
worker.push(new Worker("./IPFSUpload_worker.js"))
worker[i].onmessage = function(event) {
uploadedChunkCnt += event.data.uploadedChunkCnt
console.log("The number of Worker Thread which has done: ", uploadedChunkCnt);
hashBuffer[event.data.thread_no] = event.data.hashBuffer
if (uploadedChunkCnt == numOfChunks) {
console.log("All chunks are downloaded. Creating indexHash on IPFS...")
var chunkMap = ""
for (var j = 0; j < numOfChunks; j++) {
chunkMap = chunkMap + hashBuffer[j] + ','
}
ipfs[0].add(Ipfs.Buffer.from(chunkMap)).then((res) => {
indexHash = res[0].hash
var uploadFileSize = fullLength // byte
var uploadEndTime = new Date();
var uploadInterval = uploadEndTime - uploadStartTime // ms
var uploadSpeed = uploadFileSize / uploadInterval // byte / ms == kb/s
console.log('* upload hash:', indexHash)
console.log('* chunkMap:', chunkMap);
console.log('* upload path:', event.data.path)
console.log('* upload size:', formatSizeUnits(uploadFileSize))
console.log('* upload speed:', uploadSpeed, 'kb/s')
console.log('* upload interval:', uploadInterval / 1000, 'sec')
});
}
}
}
chooseClient()
}
$('#num_of_chunks').on('change', function() {
for (var i = 0; i < numOfChunks; i++) {
if (typeof(worker[i]) != 'undefined') {
worker[i].terminate()
}
}
init()
})
init();
})
function sendIpfsWebWorker() {
uploadStartTime = new Date();
var path = $("#file").val().split("\\")[2]
console.log("> start upload (api): ", path, uploadStartTime)
uploadedChunkCnt = 0;
var params = new Array()
for (var i = 0; i < numOfChunks; i++) {
data = {
"thread_no": i,
//"ipfs": ipfs, // 메소드는 직렬화 할수 없다..
"functionToCall": "",
"selectedClient": $('#ipfs_client').val(),
"numOfChunksInThread": 1,
"uploadBuf": uploadBuf[i],
"downloadBuf": downloadBuf[i],
"fullLength": fullLength,
"path": path,
"uploadedChunkCnt": uploadedChunkCnt
//results:,
//hashBuffer:,
}
params.push(data)
params[i] = JSON.parse(JSON.stringify(params[i]));
worker[i].postMessage(params[i])
//console.log(params[i])
//console.log("stringify params:", params[i])
}
//console.log("stringify params:", params[0])
}
async function getBandWidth() {
bw = await node.stats.bw()
$('#bwTotalIn').html(formatSizeUnits(bw.totalIn.toString().slice(0, 5)));
$('#bwTotalOut').html(formatSizeUnits(bw.totalOut.toString().slice(0, 5)));
$('#bwRateIn').html(formatSizeUnits(bw.rateIn.toString().slice(0, 5)) + '/s');
$('#bwRateOut').html(formatSizeUnits(bw.rateOut.toString().slice(0, 5)) + '/s');
}
const reader = new FileReader();
var loadFile = function(event) {
console.log('upload::');
const reader = new FileReader();
reader.onload = function() {
console.log('onload::');
onloadfile = reader
//buf = Ipfs.Buffer(reader.result); // Convert data into buffer
// split the file it will be uploaded
fullLength = reader.result.byteLength;
chunkLength = fullLength / numOfChunks
for (var i = 0; i < numOfChunks; i++) {
var chunk
if (i == numOfChunks - 1) { // last chunk process
chunk = reader.result.slice(i * chunkLength, fullLength)
} else {
chunk = reader.result.slice(i * chunkLength, (i + 1) * chunkLength)
}
uploadBuf[i] = Ipfs.Buffer(chunk)
}
};
const file = document.getElementById("file");
reader.readAsArrayBuffer(file.files[0]); // Read Provided File
};
async function sendIpfs() {
var uploadStartTime = new Date();
console.log("> start upload (api): ", uploadStartTime)
var path = $("#file").val().split("\\")[2]
results = new Array(numOfChunks)
hashBuffer = new Array(numOfChunks)
uploadedChunkCnt = 0;
for (var i = 0; i < numOfChunks; i++) {
var chunkStartTime = new Date();
console.log("start upload chunk[", i, "](api): ", chunkStartTime)
ipfs[i].add([{
path: path + '.nemo.' + i,
content: uploadBuf[i],
}], {
recursive: true,
wrapWithDirectory: true
//progress: (length) => {
// console.log(length);
//}
}).then((res) => {
var token = res[0].path.split('.')
var chunkNum = token[token.length - 1]
results[chunkNum] = res;
console.log(results[chunkNum]);
var chunkEndTime = new Date();
var chunkInterval = chunkEndTime - chunkStartTime // ms
var chunkSize = uploadBuf[chunkNum].length // byte
var speed = chunkSize / chunkInterval // byte / ms == kb/s
console.log('interval upload chunk[', chunkNum, '](api): ', chunkInterval / 1000, 'size:', chunkSize / 1000, 'kb', speed, 'kb/s')
hashBuffer[chunkNum] = results[chunkNum][1].hash;
console.log(hashBuffer[chunkNum]);
uploadedChunkCnt++;
if (uploadedChunkCnt == numOfChunks) {
var chunkMap = ""
for (var j = 0; j < numOfChunks; j++) {
chunkMap = chunkMap + hashBuffer[j] + ','
}
ipfs[0].add(Ipfs.Buffer.from(chunkMap)).then((res) => {
indexHash = res[0].hash
var uploadFileSize = fullLength // byte
var uploadEndTime = new Date();
var uploadInterval = uploadEndTime - uploadStartTime // ms
var uploadSpeed = uploadFileSize / uploadInterval // byte / ms == kb/s
console.log('* upload hash:', indexHash)
console.log('* chunkMap:', chunkMap);
console.log('* upload path:', path)
console.log('* upload size:', formatSizeUnits(uploadFileSize))
console.log('* upload speed:', uploadSpeed, 'kb/s')
console.log('* upload interval:', uploadInterval / 1000, 'sec')
});
}
})
}
}
function formatSizeUnits(bytes) {
if (bytes >= 1073741824) {
bytes = (bytes / 1073741824).toFixed(2) + " GB";
} else if (bytes >= 1048576) {
bytes = (bytes / 1048576).toFixed(2) + " MB";
} else if (bytes >= 1024) {
bytes = (bytes / 1024).toFixed(2) + " KB";
} else if (bytes > 1) {
bytes = bytes + " bytes";
} else if (bytes == 1) {
bytes = bytes + " byte";
} else {
bytes = "0 bytes";
}
return bytes;
}
</script>
</html>
IPFSUpload_worker.js
var window = {}
importScripts('./js/ipfs_index.js');
importScripts('./js/ipfs-http-client_index.js');
self.IpfsHttpClient = window.IpfsHttpClient
self.Ipfs = window.Ipfs
function createClient(context) {
context.ipfs = new Array(context.numOfChunksInThread)
if (context.selectedClient == 'infura') {
for (var i = 0; i < context.numOfChunksInThread; i++) {
context.ipfs[i] = self.IpfsHttpClient({
host: 'ipfs.infura.io',
port: 5001,
protocol: 'https'
});
}
}
}
async function sendIpfsWebWorker(context) {
createClient(context)
console.log("context in worker: ", context)
context.results = new Array(context.numOfChunksInThread)
context.hashBuffer = new Array(context.numOfChunksInThread)
context.uploadedChunkCnt = 0;
for (var i = 0; i < context.numOfChunksInThread; i++) {
var chunkStartTime = new Date();
console.log("start upload chunk[", context.thread_no, "](api): ", chunkStartTime)
context.ipfs[i].add([{
path: context.path + '.nemo.' + context.thread_no,
content: Ipfs.Buffer(context.uploadBuf.data),
}], {
recursive: true,
wrapWithDirectory: true
//progress: (length) => {
// console.log(length);
//}
}).then((res) => {
var token = res[0].path.split('.')
var chunkNum = token[token.length - 1]
context.results[chunkNum] = res;
console.log(context.results[chunkNum]);
var chunkEndTime = new Date();
var chunkInterval = chunkEndTime - chunkStartTime // ms
var chunkSize = context.uploadBuf.data.length // byte
var speed = chunkSize / chunkInterval // byte / ms == kb/s
console.log('interval upload chunk[', chunkNum, '](api): ', chunkInterval / 1000, 'size:', chunkSize / 1000, 'kb', speed, 'kb/s')
context.hashBuffer = context.results[chunkNum][1].hash;
console.log(context.hashBuffer);
context.uploadedChunkCnt++;
var resultForMainThread = JSON.parse(JSON.stringify(context));
postMessage(resultForMainThread);
self.close()
})
}
}
function formatSizeUnits(bytes) {
if (bytes >= 1073741824) {
bytes = (bytes / 1073741824).toFixed(2) + " GB";
} else if (bytes >= 1048576) {
bytes = (bytes / 1048576).toFixed(2) + " MB";
} else if (bytes >= 1024) {
bytes = (bytes / 1024).toFixed(2) + " KB";
} else if (bytes > 1) {
bytes = bytes + " bytes";
} else if (bytes == 1) {
bytes = bytes + " byte";
} else {
bytes = "0 bytes";
}
return bytes;
}
onmessage = function(event){
sendIpfsWebWorker(event.data);
}
index.html:275 upload::
index.html:279 onload::
index.html:197 > start upload (api): harry_potter_hermione_growth_spurt_snl_720p.mp4 Fri Aug 16 2019 09:48:28 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:39 context in worker: {thread_no: 0, functionToCall: "", selectedClient: "infura", numOfChunksInThread: 1, uploadBuf: {…}, …}
IPFSUpload_worker.js:52 start upload chunk[ 0 ](api): Fri Aug 16 2019 09:48:45 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:68 (2) [{…}, {…}]
IPFSUpload_worker.js:73 interval upload chunk[ 0 ](api): 15.69 size: 51340.408 kb 3272.1738687061825 kb/s
IPFSUpload_worker.js:76 QmNqHoM9cyNeXH1QLUZt2sZtBY8DgoYB8aD7WFBHccK5VD
index.html:154 The number of Worker Thread which has done: 1
index.html:157 All chunks are downloaded. Creating indexHash on IPFS...
index.html:168 * upload hash: QmPYTrBBZVHPusoUP3oRsaD3T25ccY2LFbUYCgAUvkWuFP
index.html:169 * chunkMap: QmNqHoM9cyNeXH1QLUZt2sZtBY8DgoYB8aD7WFBHccK5VD,
index.html:170 * upload path: harry_potter_hermione_growth_spurt_snl_720p.mp4
index.html:171 * upload size: 48.96 MB
index.html:172 * upload speed: 904.9797817771589 kb/s
index.html:173 * upload interval: 56.731 sec
index.html:275 upload::
index.html:279 onload::
index.html:197 > start upload (api): harry_potter_hermione_growth_spurt_snl_720p.mp4 Fri Aug 16 2019 09:55:30 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:39 context in worker: {thread_no: 0, functionToCall: "", selectedClient: "infura", numOfChunksInThread: 1, uploadBuf: {…}, …}
IPFSUpload_worker.js:52 start upload chunk[ 0 ](api): Fri Aug 16 2019 09:55:33 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:39 context in worker: {thread_no: 1, functionToCall: "", selectedClient: "infura", numOfChunksInThread: 1, uploadBuf: {…}, …}
IPFSUpload_worker.js:52 start upload chunk[ 1 ](api): Fri Aug 16 2019 09:55:35 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:39 context in worker: {thread_no: 2, functionToCall: "", selectedClient: "infura", numOfChunksInThread: 1, uploadBuf: {…}, …}
IPFSUpload_worker.js:52 start upload chunk[ 2 ](api): Fri Aug 16 2019 09:55:37 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:39 context in worker: {thread_no: 3, functionToCall: "", selectedClient: "infura", numOfChunksInThread: 1, uploadBuf: {…}, …}
IPFSUpload_worker.js:52 start upload chunk[ 3 ](api): Fri Aug 16 2019 09:55:39 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:39 context in worker: {thread_no: 4, functionToCall: "", selectedClient: "infura", numOfChunksInThread: 1, uploadBuf: {…}, …}
IPFSUpload_worker.js:52 start upload chunk[ 4 ](api): Fri Aug 16 2019 09:55:42 GMT+0900 (한국 표준시)
IPFSUpload_worker.js:68 (2) [{…}, {…}]
IPFSUpload_worker.js:73 interval upload chunk[ 2 ](api): 16.813 size: 10268.081 kb 610.7227145661095 kb/s
IPFSUpload_worker.js:76 QmNzJqR3snVWQexVQA7crYNV4bJEjxMT9EHzhL5bSrBB5W
index.html:154 The number of Worker Thread which has done: 1
IPFSUpload_worker.js:68 (2) [{…}, {…}]
IPFSUpload_worker.js:73 interval upload chunk[ 0 ](api): 23.512 size: 10268.081 kb 436.71661279346716 kb/s
IPFSUpload_worker.js:76 QmSoruLfXkR51MVRUrcbBetGW4StkjfvxPAdn7yDoHdBUV
IPFSUpload_worker.js:68 (2) [{…}, {…}]
IPFSUpload_worker.js:73 interval upload chunk[ 3 ](api): 18.422 size: 10268.082 kb 557.3815003799805 kb/s
IPFSUpload_worker.js:76 QmY9KdJwnLsWcjYQCxNUECTFx82EhJf9CYBEZhQxqa38Ev
index.html:154 The number of Worker Thread which has done: 2
index.html:154 The number of Worker Thread which has done: 3
IPFSUpload_worker.js:68 (2) [{…}, {…}]
IPFSUpload_worker.js:73 interval upload chunk[ 1 ](api): 25.713 size: 10268.082 kb 399.3342667133357 kb/s
IPFSUpload_worker.js:76 Qmbx4svY1z6LhTje2gJinwQqNaDwjgt8fJsiNJh9fmSjnT
index.html:154 The number of Worker Thread which has done: 4
IPFSUpload_worker.js:68 (2) [{…}, {…}]
IPFSUpload_worker.js:73 interval upload chunk[ 4 ](api): 23.085 size: 10268.082 kb 444.79454191033136 kb/s
IPFSUpload_worker.js:76 QmeVYG86BNcqfhy6RjtGEM6dSFo33cfNFM4Ebniop4cAmf
index.html:154 The number of Worker Thread which has done: 5
index.html:157 All chunks are downloaded. Creating indexHash on IPFS...
index.html:168 * upload hash: QmdnbFQQJ4HhbvE2nNcJ9jhJmajGd83qdNxFkcQkgAXeNk
index.html:169 * chunkMap: QmSoruLfXkR51MVRUrcbBetGW4StkjfvxPAdn7yDoHdBUV,Qmbx4svY1z6LhTje2gJinwQqNaDwjgt8fJsiNJh9fmSjnT,QmNzJqR3snVWQexVQA7crYNV4bJEjxMT9EHzhL5bSrBB5W,QmY9KdJwnLsWcjYQCxNUECTFx82EhJf9CYBEZhQxqa38Ev,QmeVYG86BNcqfhy6RjtGEM6dSFo33cfNFM4Ebniop4cAmf,
index.html:170 * upload path: harry_potter_hermione_growth_spurt_snl_720p.mp4
index.html:171 * upload size: 48.96 MB
index.html:172 * upload speed: 1189.9503534592652 kb/s
index.html:173 * upload interval: 43.145 sec
for (var i = 0; i < numOfChunks; i++) {
ipfs[i] = window.IpfsHttpClient({
host: 'ipfs.infura.io',
port: 5001,
protocol: 'https',
});
}
...
for (var i = 0; i < numOfChunks; i++) {
ipfs[i].add([{
path: path + '.nemo.' + i,
content: uploadBuf[i],
}], {
recursive: true,
wrapWithDirectory: true
}).then((res) => {
... // do the job I intended.
})
}