Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在两个异步操作之间暂停?_Javascript_Node.js_Asynchronous_Mikrotik_Router Os - Fatal编程技术网

Javascript 如何在两个异步操作之间暂停?

Javascript 如何在两个异步操作之间暂停?,javascript,node.js,asynchronous,mikrotik,router-os,Javascript,Node.js,Asynchronous,Mikrotik,Router Os,我需要在“/system/backup/save”和“/file/print”之间暂停。否则,在显示“/file”目录的内容之前,备份将无法完成。 现在代码正在执行备份,但它给了我一个还没有备份的文件列表 const RouterOSAPI = require("node-routeros").RouterOSAPI; const sleep = require('util').promisify(setTimeout); var hosts = require('./con

我需要在“/system/backup/save”和“/file/print”之间暂停。否则,在显示“/file”目录的内容之前,备份将无法完成。 现在代码正在执行备份,但它给了我一个还没有备份的文件列表

const RouterOSAPI = require("node-routeros").RouterOSAPI;
const sleep = require('util').promisify(setTimeout);
var hosts = require('./config.json');

async function backup() {
    return new Promise(function (resolve, reject) {

        for (let elem of hosts) {
            const conn = new RouterOSAPI({
                host: elem.host,
                user: elem.user,
                password: elem.password
            })
            conn.connect()
                .then((client) => {
                    return conn.write(["/system/backup/save",]).then((data) => {
                        resolve('COMPLETE - OK');
                    }).catch((err) => {
                        reject('ERROR!');
                    });
                    sleep(5000);
                }).then(() => {
                return conn.write("/file/print").then((data2) => {
                    console.log(data2)
                    resolve('CHECK - OK');
                    conn.close();
                }).catch((err) => {
                    reject('ERROR!');
                });

            }).catch((err) => {
                reject('ERROR CONNECT TO ' + elem.name);
            });
        }
    });
}

backup();

通常,使用延迟等待异步进程的完成是一种反模式,您最终要么等待的时间不够长,要么等待的时间过长。前者当然是比后者更大的问题,但两者都是问题。如果您有任何方法让另一端报告备份完成,那将是您的最佳选择。现在看来,在操作完成之前,
conn.write
的承诺不应该兑现,但我只是浏览了一下文档,所以可能不是这样

除此之外:

  • 不要显式地创建承诺,您的
    async
    函数会自动创建承诺(但您可能不希望在此处使用
    async
    函数)

  • 不要混合使用
    。然后
    /
    。用
    异步
    函数捕获
    处理程序;使用
    等待

  • 例如,下面是一个并行运行备份等的版本,它通过以下方式返回一个成功/失败的阵列:

    但是请注意,由于该函数只是从
    allsolited
    返回承诺,因此您可能根本不需要
    async
    函数:

    const RouterOSAPI = require("node-routeros").RouterOSAPI;
    const sleep = require('util').promisify(setTimeout);
    var hosts = require('./config.json');
    
    function backup() {
        // Run the hosts in parallel
        return Promise.allSettled(hosts.map(async (host) => {
            let conn;
            try {
                const c = new RouterOSAPI({
                    host: elem.host,
                    user: elem.user,
                    password: elem.password
                })
                const client = await c.connect();
                conn = c;
                await conn.write(["/system/backup/save",]);
                await sleep(5000); // Only if really unavoidable because the 
                                   // backup continues even after the promise
                                   // from `write` is fulfilled
                await conn.write("/file/print");
                conn = null;
                c.close();
            } catch (e) {
                if (conn) {
                    try {
                        conn.close();
                    } catch {} // Don't let errors in close shadow previous errors
                }
                throw e;
            }
        }));
    }
    
    backup()
    .then(results => {
        // Check for status = "rejected" entries in results and report the errors
    });
    

    (如果
    hosts.map
    抛出一个错误(可能是因为
    hosts
    不是一个数组),这两者之间会有细微的区别,但这可能并不重要。前者返回一个被拒绝的承诺,后者抛出一个同步错误。)

    而不是sleep>。使用承诺等待行动完成。避免错误!
    resolve()
    reject()
    调用将无法在该循环中正常工作。另一端是否无法告诉您备份何时完成?另外:如果你有一个
    async
    函数,你不需要显式地创建承诺,而且你通常不想使用
    。然后
    等附加处理程序(改为使用
    wait
    )。
    sleep(5000)
    做什么?它创造了一个承诺,你必须
    返回
    这个承诺!尽管@John是正确的,但你不应该在那里睡觉,而应该等待写作完成。
    
    const RouterOSAPI = require("node-routeros").RouterOSAPI;
    const sleep = require('util').promisify(setTimeout);
    var hosts = require('./config.json');
    
    function backup() {
        // Run the hosts in parallel
        return Promise.allSettled(hosts.map(async (host) => {
            let conn;
            try {
                const c = new RouterOSAPI({
                    host: elem.host,
                    user: elem.user,
                    password: elem.password
                })
                const client = await c.connect();
                conn = c;
                await conn.write(["/system/backup/save",]);
                await sleep(5000); // Only if really unavoidable because the 
                                   // backup continues even after the promise
                                   // from `write` is fulfilled
                await conn.write("/file/print");
                conn = null;
                c.close();
            } catch (e) {
                if (conn) {
                    try {
                        conn.close();
                    } catch {} // Don't let errors in close shadow previous errors
                }
                throw e;
            }
        }));
    }
    
    backup()
    .then(results => {
        // Check for status = "rejected" entries in results and report the errors
    });