Синхронизация кода на node.js не работает...



  •     await (new Promise((resolve, reject) => {
    const { ImapFlow } = require('imapflow');
    const client = new ImapFlow({
        host: 'secureimap.t-online.de',
        port: 993,
        secure: true,
        auth: {
            user: 'bjarne.fuellengraben@t-online.de',
            pass: 'Bornholm1,'
        }
    });
     
    const main = async () => {
    
        await client.connect();
     
        let lock = await client.getMailboxLock('INBOX');
        try {
    
            let message = await client.fetchOne('*', { source: true });
            console.log(message.source.toString());
     
    
            for await (let message of client.fetch('1:*', { envelope: true })) {
                console.log(`${message.uid}: ${message.envelope.subject}`);
            }
        } finally {
    
            lock.release();
        }
     
    
        await client.logout();
    };
     
    main().catch(err => console.error(err));
    	resolve()
    }));
    
    

    Вроде всё сделал правильно, код так и не сработал, логично что это связано с синхронизацией, но почему у меня она не сработала?(



  • Решил проблему, в общем, с конца надо удалять "resolve()"

    То есть

    Не так:

    await (new Promise((resolve, reject) => {
    	/*Place your code here and call resolve to proceed*/
    	resolve()
    }));
    

    А так:

    await (new Promise((resolve, reject) => {
    	/*Place your code here and call resolve to proceed*/
    }));
    


  • @ynvazius said in Синхронизация кода на node.js не работает...:

    Решил проблему, в общем, с конца надо удалять "resolve()"

    @support said in websocket на node js:

    Если код на node.js работает не так как вы хотите, то есть большая вероятность, что проблемы с асинхронностью.
    Вот способ все исправить, даже не понимая, что случилось:

    1. Нажимаем на кнопку синхронизировать на панели справа. Появляется такой код
    await (new Promise((resolve, reject) => {
    	/*Place your code here and call resolve to proceed*/
    	resolve()
    }));
    
    1. Вместо комментария /*Place your code here and call resolve to proceed*/ помещаем свой код.
    2. Вызов resolve() переносим туда, где действие должно закончиться. Например, в примере с вебсокетами, это место, где нам приходит ответ от сервера.

    alt text

    Почему так?

    Очень часто примеры на ноде только устанавливают обработчики события. Например, когда кнопка будет нажата, отобразить окно с сообщением. Или когда придет сообщение от сервера, отобразить его в лог.
    Но сама установка события происходит мгновенно. Здесь речь идет именно об установке события, а не ожидании самого события. То есть, установить обработчик клика по кнопке можно мгновенно, а вот ждать этого клика можно сколько угодно. Синхронизация позволяет именно дождаться самого события.

    Почему пример в теме не всегда работает, и что с глобальными переменными?

    БАС говорит ноде сделать запрос к серверу, говорит, что нужно сделать, когда соединение откроется или придет сообщение от сервера или соединение закроется(выставляет обработчики). После этого, действие node.js сразу завершается. Но сам код в node.js работает, делает запрос к серверу и устанавливает глобальную переменную(global.tost). Следующий вызов действия node.js читает эту глобальную переменную и выводит ее в лог(console.log(global.tost);). Но тут проблема. К тому времени, как мы читаем глобальную переменную, ответ от сервера не обязательно получен. Его может быть, а может и не быть. Именно поэтому, я все таки рекомендую использовать решение с синхронизацией.

    А нельзя ли сделать все автоматом?

    Нет, так не получится. Главная проблема тут, куда поместить вызов resolve? Напомню, resolve нужно вызывать тогда, когда действие должно быть завершено(в нашем случае получено сообщение от сервера). Код может быть более сложным и определить место, где будет resolve автоматически будет очень сложно. Например, если нода должна не просто получить одно сообщение от сервера, а обменяться несколькими, или опрашивать сервер, пока не будет получен нужный результат.
    Есть вариант, когда действие завершается после того, как нет активных вызовов(например запросов к серверу), но я предпочитаю такой вариант, с явным заданием места, где действие завершается.

    Все равно сложно!

    Да, это самая неприятная часть в ноде. Но у нее есть и множество достоинств. Например, выигрыш производительности за счет отсутствия необходимости создания потоков для параллельных вычислений. Это касается в основном работы с сетью и записи, чтения файлов, но так как именно работе с сетью в БАС уделяется огромное внимание, то это большой плюс. Нет необходимости обеспечивать целостность данных при работе с одними и теми же участками памяти из нескольких потоков.

    Для тех, кто хочет изучить, как использовать ноду в БАС более детально есть статья(на английском) https://wiki.bablosoft.com/doku.php?id=node.js и видео на русском https://www.youtube.com/watch?v=YojWxGcGGEg

    Также в БАС будут добавлены и другие языки, как я и обещал.



  • Тот случай когда, методом тыка что-то заработало
    @ynvazius said in Синхронизация кода на node.js не работает...:

    Решил проблему, в общем, с конца надо удалять "resolve()"

    То есть

    Не так:

    await (new Promise((resolve, reject) => {
    	/*Place your code here and call resolve to proceed*/
    	resolve()
    }));
    

    А так:

    await (new Promise((resolve, reject) => {
    	/*Place your code here and call resolve to proceed*/
    }));
    

    А вот как надо было

    const { ImapFlow } = require('imapflow');
    const client = new ImapFlow({
        host: 'secureimap.t-online.de',
        port: 993,
        secure: true,
        auth: {
            user: 'bjarne.fuellengraben@t-online.de',
            pass: 'Bornholm1,'
        }
    });
     
    
    
    await client.connect();
    
    let lock = await client.getMailboxLock('INBOX');
    try {
    
    	let message = await client.fetchOne('*', { source: true });
    	console.log(message.source.toString());
    
    
    	for await (let message of client.fetch('1:*', { envelope: true })) {
    		console.log(`${message.uid}: ${message.envelope.subject}`);
    	}
    } finally {
    
    	lock.release();
    }
    
    
    await client.logout();
    
    


  • @UserTrue ...
    Спасибо...

    Я в а***, но не об этом, ты мне сохранил час жизни!



  • @GhostZ глупый я, соре;)


Log in to reply