Javascript 带承诺的脚本执行顺序

Javascript 带承诺的脚本执行顺序,javascript,node.js,promise,Javascript,Node.js,Promise,我知道这个问题和这个问题几乎是一样的:但是有人能向我解释一下我的错误在哪里吗? 我有以下功能: // The main function function startTesting() { console.info("--- Thanks! Testing is running... ---"); checkFolderExistence(dirPath) .then(checkFolderContent) .then(searchForImpor

我知道这个问题和这个问题几乎是一样的:但是有人能向我解释一下我的错误在哪里吗? 我有以下功能:

// The main function
function startTesting() {
    console.info("--- Thanks! Testing is running... ---");
    checkFolderExistence(dirPath)
        .then(checkFolderContent)
        .then(searchForImportFolder)
        .then(connectToDB)
        .catch(err => console.error("*** ERROR *** " + err));
}

function checkFolderExistence(path) {
    console.info('--- Checking the folder "' + path + '" existence... ---');
    let promise = new Promise(function(resolve, reject) {
        fs.readdir(path, (err) => {
            if(err) {
                console.error('*** ERROR **** The folder "C:\\For_testing" doesn\'t exist. Testing is stopped!!! ***');
            } else {
                console.info("--- The folder \"C:\\For_testing\" exists... ---");
                resolve(path);
            };
        });
    });
    return promise;
}

function checkFolderContent(path) {
    console.info('--- Checking the folder "' + path + '" content... ---');
    filesArray = fs.readdirSync(path);
    if(filesArray.length == 0) {
        console.error('*** ERROR *** There are no any files in ' + path + '. Testing is stopped!!! ***');
    } else {
        console.info('--- The folder is checked. It contains the next files: ---');
        for(let i = 0; i < filesArray.length; i++) {
            console.info(filesArray[i]);
        }
    };
}

function searchForImportFolder() {
    console.info('--- Searching for ".../Import" folder... ---');
    fs.readdir(destFolderPath64, (err) => {
        if(err) {
            fs.readdir(destFolderPath32, (err) => {
                if(err) {
                    console.error('*** ERROR *** The folder ".../Import" was not found ***');
                } else {
                    console.info('--- The folder ".../Import" was successfully found... ---');
                    trueDestPath = destFolderPath32;
                }
            });
        } else {
            console.info('--- The folder "C:/Program Files (x86)/StoreLine/Office/Import" was successfully found... ---');
            trueDestPath = destFolderPath64;
        }
    });
}

function connectToDB() {
    console.info('--- Connecting to the database... ---');
    let pool = new sql.ConnectionPool(config);
    pool.connect()
        .then(pool => {
            console.info("--- Connected to the database! ---");
            readDB(pool)
                .then(function() {
                    console.info("--- All needed information from DB was successfully received ---");
            })
                 .catch(err => console.error("*** ERROR *** " + err));
        })
        .catch(err => {
            pool = new sql.ConnectionPool(configWithoutPassw);
            pool.connect()
                .then(pool => {
                    console.info("--- Connected to the database without the password! ---");
                    readDB(pool)
                        .then(function() {
                            console.info("--- All needed information from the DB was successfully received ---");
                        })
                        .catch(err => console.error("*** ERROR ***" + err));
                })
                .catch(err => {
                    console.error("*** ERROR *** Can't connect to the DB ***")
                    sql.close();
                });
        });
}
//主函数
函数startTesting(){
console.info(“---谢谢!测试正在运行…”);
checkFolderExistence(目录路径)
。然后(检查文件夹内容)
.然后(搜索导入文件夹)
.然后(连接到B)
.catch(err=>console.error(“***error***”+err));
}
函数checkFolderExistence(路径){
console.info('---检查文件夹'+path+''是否存在…--');
让承诺=新承诺(功能(解决、拒绝){
fs.readdir(路径,(错误)=>{
如果(错误){
控制台。错误('***错误****文件夹“C:\\For\u testing”不存在。测试已停止!!!***');
}否则{
console.info(“----文件夹\“C:\\用于测试\”存在…--”);
解决(路径);
};
});
});
回报承诺;
}
函数checkFolderContent(路径){
console.info('---检查文件夹“'+path+'”内容…--');
filesArray=fs.readdirSync(路径);
如果(filesArray.length==0){
console.error('***error***在'+path+'中没有任何文件。测试已停止!!!***');
}否则{
console.info('---文件夹已选中。它包含下一个文件:---');
for(设i=0;i{
如果(错误){
fs.readdir(destFolderPath32,(err)=>{
如果(错误){
console.error(“***错误***未找到文件夹“../Import***”);
}否则{
console.info('---已成功找到文件夹“../Import…”--);
trueDestPath=destFolderPath32;
}
});
}否则{
console.info('--成功找到文件夹“C:/ProgramFiles(x86)/StoreLine/Office/Import…”--);
trueDestPath=destFolderPath64;
}
});
}
函数connectToDB(){
console.info('---连接到数据库…--');
让pool=newsql.ConnectionPool(config);
pool.connect()
。然后(池=>{
console.info(“---已连接到数据库!-->”);
readDB(池)
.然后(函数(){
console.info(“---成功接收到来自DB的所有所需信息---”);
})
.catch(err=>console.error(“***error***”+err));
})
.catch(错误=>{
池=新的sql.ConnectionPool(configWithoutPassw);
pool.connect()
。然后(池=>{
console.info(“---已连接到数据库,但没有密码!-->”);
readDB(池)
.然后(函数(){
console.info(“---成功接收到来自数据库的所有所需信息---”);
})
.catch(err=>console.error(“***error***”+err));
})
.catch(错误=>{
控制台错误(“***错误***无法连接到数据库***”)
sql.close();
});
});
}
我需要严格的函数执行顺序:
checkFolderContent
=>
searchForImportFolder
=>
connectToDB

事实上,执行是下一步:
checkFolderContent
被完全执行,然后
searchForImportFolder
开始执行(我可以看到控制台中的行“---搜索“../Import”文件夹…-”),但紧接着,
connectToDB
开始,出现下一行“---连接到数据库…-”。在那一行之后,我看到前面函数中的“---文件夹“../Import”被成功地找到了…--”


我做错了什么?我在
中读到过。then()
函数应该返回一个承诺。我该怎么做?

searchForImportFolder不会返回承诺,因此链不会等待该承诺完成。在
searchForImportFolder
中执行与在
checkFolderExistence
中相同的操作:将回调样式API包装在承诺中

几点注意:

  • checkFolderExistence
    应在错误路径中调用
    reject
    ;目前还没有
  • 节点提供了一个函数,您可以使用该函数将回调样式的API调用封装在承诺中,而不是手动执行。或者,您可以使用,或允许您一次发布整个API的,或节点自己的
  • 您可能希望使
    checkFolderContent
    异步(再次使用promissions),而不是使用
    readdirSync
    ,这会占用等待I/O的主线程
  • 如果您使用的是Node的任何最新版本,您可能希望切换到使用
    async
    函数和
    wait
    关键字,因为它允许您编写逻辑流,而不是编写一堆回调
  • searchForImportFolder
    应返回其结果,而不是设置全局值
例如,这里有使用
util.promisify
checkFolderExistence
searchForImportFolder
(这些假设
searchForImportFolder
应该返回其结果,因此您必须使用它调整代码):

如果您不需要所有这些日志记录,
checkFolderExistence
只会变成
readdirPromise
,而
searchForImportFolder
变成:

或者,如果您不需要所有日志记录(可能是为了调试):

这里他们使用的是
util.promisify
asyncconst { promisify } = require("util");

const readdirPromise = promisify(fs.readdir);

function checkFolderExistence(path) {
    console.info('--- Checking the folder "' + path + '" existence... ---');
    return readdirPromise(path)
        .then(path => {
            console.info("--- The folder \"C:\\For_testing\" exists... ---");
            return path;
        })
        .catch(error => {
            console.error('*** ERROR **** The folder "C:\\For_testing" doesn\'t exist. Testing is stopped!!! ***');
        });
}

// ...

function searchForImportFolder() {
    console.info('--- Searching for ".../Import" folder... ---');
    return readdirPromise(destFolderPath64)
        .then(() => {
            console.info('--- The folder "C:/Program Files (x86)/StoreLine/Office/Import" was successfully found... ---');
            return destFolderPath64;
        })
        .catch(() => readdirPromise(destFolderPath32))
        .then(() => {
            console.info('--- The folder ".../Import" was successfully found... ---');
            return destFolderPath32;
        })
        .catch(error => {
            console.error('*** ERROR *** The folder ".../Import" was not found ***');
            throw error;
        });
}
const { promisify } = require("util");

const readdirPromise = promisify(fs.readdir);

// ...

function searchForImportFolder() {
    console.info('--- Searching for ".../Import" folder... ---');
    return readdirPromise(destFolderPath64)
        .then(() => {
            return destFolderPath64;
        })
        .catch(() => readdirPromise(destFolderPath32));
}
const { promisify } = require("util");

const readdirPromise = promisify(fs.readdir);

// ...

async function searchForImportFolder() {
    try {
        await readdirPromise(destFolderPath64);
        return destFolderPath64;
    } catch (error) {
        await readdirPromise(destFolderPath32);
        return destFolderPath32;
    }
}
const importFolderPromise = searchForImportFolder();
importFolderPromise.then(folder => {/*...*/});
const folder = await importFolderPromise;