我对异步函数太陌生了,如果我弄错了,很抱歉。目前,我已尝试使用 mscdex node-ftp 节点包通过 FTP 上传给定目录中的所有文件夹。虽然这很完美,但承诺在我的函数中解析得太早,并且会在上传完全完成之前在主函数中运行其他代码。
有没有办法让uploadFolder函数只有在uploadFolder函数完全完成后才运行代码?
var c = new Client(config);
let uploadFolder = (folderToUpload) => {
try {
return new Promise((resolve, reject) => {
let folderName = folderToUpload.substring(
folderToUpload.lastIndexOf("/") + 1
);
let replacedItem = folderToUpload.replace(folderName, "");
let uploadOrder = Glob.sync(folderToUpload + "/**/*");
c.on("ready", () => {
let uploadOrderFiltered = uploadOrder.map((element) => {
return element.replace(replacedItem, "");
});
c.mkdir(`/${folderName}`, false, (error) => {
if (error) {
console.log(`Error, MKDIR Error ${error}`);
c.end();
}
});
for (let i = 0; i < uploadOrderFiltered.length; i++) {
if (uploadOrderFiltered[i].includes(".")) {
c.put(
`${replacedItem}${uploadOrderFiltered[i]}`,
`/${uploadOrderFiltered[i]}`,
(error) => {
if (error) {
console.log(`Error, UPLOADING Error ${error}`);
c.end();
}
}
);
} else {
c.mkdir(`/${uploadOrderFiltered[i]}`, false, (error) => {
if (error) {
console.log(`Error, MKDIR Error ${error}`);
c.end();
}
});
}
}
c.end();
});
c.connect(config);
resolve();
});
} catch (error) {
console.log(`[FTP ERROR]: ${error}`);
reject();
}
};
const { createFolder } = require("./createFolder");
let asyncFunc = async () => {
// ... CODE BEFORE (Runs Fine)
//PROMISE BROKEN
await uploadFolder(
"D:/GitHub/Procedural-Artwork-Generation/nexRender/Project/Output/zeroTwoTemplate_AJDKAJKDJKADJKA"
);
console.log("[FTP]: Upload Done");
//Upload Done is running before uploadFolder function is completed.
提前感谢您的帮助。
答案 0 :(得分:0)
解决方案正如jfriend00所说,我太早解决了我的承诺。我最终做的是用 c.on("ready") 块之外的单独事件处理程序替换 resolve() 方法,该处理程序侦听“end”事件。
更新后的代码如下
var c = new Client(config);
let uploadFolder = (folderToUpload) => {
try {
return new Promise((resolve, reject) => {
let folderName = folderToUpload.substring(
folderToUpload.lastIndexOf("/") + 1
);
let replacedItem = folderToUpload.replace(folderName, "");
let uploadOrder = Glob.sync(folderToUpload + "/**/*");
c.on("ready", () => {
let uploadOrderFiltered = uploadOrder.map((element) => {
return element.replace(replacedItem, "");
});
c.mkdir(`/${folderName}`, false, (error) => {
if (error) {
console.log(`Error, MKDIR Error ${error}`);
c.end();
}
});
for (let i = 0; i < uploadOrderFiltered.length; i++) {
if (uploadOrderFiltered[i].includes(".")) {
c.put(
`${replacedItem}${uploadOrderFiltered[i]}`,
`/${uploadOrderFiltered[i]}`,
(error) => {
if (error) {
console.log(`Error, UPLOADING Error ${error}`);
c.end();
}
}
);
} else {
c.mkdir(`/${uploadOrderFiltered[i]}`, false, (error) => {
if (error) {
console.log(`Error, MKDIR Error ${error}`);
c.end();
}
});
}
}
c.end();
});
c.on("end", () => {
resolve();
});
c.connect(config);
});
} catch (error) {
console.log(`[FTP ERROR]: ${error}`);
reject();
}
};
答案 1 :(得分:0)
我并没有完全遵循你想要完成的所有事情,但我认为如果你使用 promise-ftp
库来封装 node-ftp 库,那么这段代码会简单得多,然后你就可以使用 async/await
对所有异步操作进行流量控制。
这是它看起来如何的一般想法(我试图复制你的逻辑,但没有真正理解你在做什么,也没有能力测试它——所以把它当作方向,而不是直接跑出来的东西框):
const Client = require('promise-ftp');
const glob = require('glob-promise');
async function uploadFolder(folderToUpload) {
let folderName = folderToUpload.substring(folderToUpload.lastIndexOf("/") + 1);
let replacedItem = folderToUpload.replace(folderName, "");
let uploadOrder = await glob(folderToUpload + "/**/*");
const c = new Client(config);
try {
await c.connect();
await c.mkdir(`/${folderName}`, false);
let uploadOrderFiltered = uploadOrder.map((element) => {
return element.replace(replacedItem, "");
});
for (let f of uploadOrderFiltered) {
if (f.includes(".")) {
await c.put(`${replacedItem}${f}`, `/${f}`);
} else {
await c.mkdir(`/${f}`, false);
}
}
} catch (e) {
console.log('FTP error: ', e);
throw e;
} finally {
c.end();
}
}
关于您的逻辑的一些观察:
glob-promise
将 promise 封装在 glob 接口周围,因此您也可以将 async/await
与它一起使用,然后使用异步版本。uploadFolder()
的调用,则会产生问题。因此,我为每个对 uploadFolder()
的单独调用创建了一个新客户端。