Новый асинхронный интерфейс

Chrome
Адаптер Рутокен Плагин 1.1.0.0
Плагин 4.11.0.0

Работаю с использованием https://github.com/AktivCo/rutoken-plugin-js

rutoken.loadPlugin() // это promise
.then(p => {
 p.login(0,'1234'); // это не promise
});

В описании - Все интерфейсные функции плагина возвращают promise
Как я могу добиться такого поведения плагина?

Re: Новый асинхронный интерфейс

zijili, добрый день!

Такой код у вас не работает?

rutoken.loadPlugin() // это promise
.then(p => {
    return p.login(0,'1234'); // это promise
})
.then(function() {
    document.write("Logged in");
});

Советую посмотреть на простой пример https://dev.rutoken.ru/pages/viewpage.a … d=30113795 и на демо-страницу Рутокен Плагин: https://aktivco.github.io/rutoken-plugin-demo/

С использованием rutoken-plugin.js из архива https://github.com/AktivCo/rutoken-plug … 1.0.10.zip такой пример у меня успешно отработал:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">

<script type="text/javascript" src="rutoken-plugin.js"></script>
<script type="text/javascript">
    window.onload = function() {
        rutoken.ready
            // Проверка установки расширение 'Адаптера Рутокен Плагина' в Google Chrome
            .then(function() {
                if (window.chrome || typeof InstallTrigger !== 'undefined') {
                    return rutoken.isExtensionInstalled();
                } else {
                    return Promise.resolve(true);
                }
            })
            // Проверка установки Рутокен Плагина
            .then(function(result) {
                if (result) {
                    return rutoken.isPluginInstalled();
                } else {
                    return Promise.reject("Не удаётся найти расширение 'Адаптер Рутокен Плагина'");
                }
            })
            // Загрузка плагина
            .then(function(result) {
                if (result) {
                    return rutoken.loadPlugin();
                } else {
                    return Promise.reject("Не удаётся найти Плагин");
                }
            })
            //Можно начинать работать с плагином
            .then(function(result) {
                if (!result) {
                    return Promise.reject("Не удаётся загрузить Плагин");
                } else {
                    plugin = result;
                    return Promise.resolve();
                }
            })
            .then(function() {
                document.getElementById("pluginStatus").innerHTML = "<pre>Плагин загрузился</pre>";
                return plugin.enumerateDevices();
            }, function(msg) {
                //document.getElementById("pluginStatus").innerHTML = "<pre>" + msg + "</pre>";
                return Promise.reject("Не удаётся загрузить Плагин");
            })
            .then(function(devices) {
                if (devices.length > 0) {
                    return Promise.resolve(devices[0]);
                } else {
                    return Promise.reject("Рутокен не обнаружен");
                }
            })
            // Проверка залогиненности
            .then(function(firstDevice) {
                rutokenHandle = firstDevice;
                return plugin.getDeviceInfo(rutokenHandle, plugin.TOKEN_INFO_IS_LOGGED_IN);
            })
            // Логин на первый токен в списке устройств PIN-кодом по умолчанию
            .then(function(isLoggedIn) {
                if (isLoggedIn) {
                    return Promise.resolve();
                } else {
                    return plugin.login(rutokenHandle, "12345678");
                }
            }).then(function() {
                document.getElementById("pluginStatus").innerHTML = "<pre>" + "Token logged in" + "</pre>";
            }).catch( msg => {
                document.getElementById("pluginStatus").innerHTML = "<pre>" + msg + "</pre>";
            });
    }
</script>

<title>Rutoken Plugin Tutorial</title>
 </head>
 <body>
 <div id="pluginStatus"><pre>Загрузка Плагина...</pre></div>
 </body> 
</html>

Re: Новый асинхронный интерфейс

Код работает, вопрос заключается в другом.

В документации указано, что реализация на promise, а по факту получаем объект в котором реализован только .then()

Я так понимаю это и есть финальная реализация, вопрос можно считать закрытым.
Спасибо за ответ!

Re: Новый асинхронный интерфейс

zijili пишет:

В документации указано, что реализация на promise, а по факту получаем объект в котором реализован только .then()

Немного не понимаю. С моей стороны и такой код работает:

rutoken.loadPlugin() // это promise
.then(p => {
    return p.login(0,'1234'); // это promise
})
.then(function() {
    document.write("Logged in");
}).catch( msg => {
    document.getElementById("pluginStatus").innerHTML = "<pre>" + msg + "</pre>";
}).finally(function() {
    document.getElementById("pluginStatus").innerHTML = document.getElementById("pluginStatus").innerHTML + "<pre>" + "Finally" + "</pre>";
});

В finally попадаю всегда под конец, в then/catch -- в зависимости от того, правильный ли PIN.

Как будто это соответствует документации на Promise: https://developer.mozilla.org/en-US/doc … ts/Promise

Re: Новый асинхронный интерфейс

zijili, я немного еще поотлаживался; после этого хотел бы заключить, что вы правы. Документация не совсем точна. Плагин из интерфейсных функций возвращает Promise-like объект с методом then.

Как проверял:

plugin.login(0, "1234567")
.then(function() {
    document.getElementById("pluginStatus").innerHTML = "<pre>" + "Token logged in" + "</pre>";
})
.catch( msg => {
    document.getElementById("pluginStatus").innerHTML = "<pre>" + msg + "</pre>";
})
.finally(
    function() {
        document.getElementById("pluginStatus").innerHTML = document.getElementById("pluginStatus").innerHTML + "<pre>" + "Finally" + "</pre>";
    }
);

PIN-код неправильный, но catch и finally не зовется. Получить сообщение об ошибке можно, если указать в then вторым параметром функцию -- обработчик ошибки (как делается в https://aktivco.github.io/rutoken-plugin-demo/ )

Как получить Promises с catch/finally с тем же примером:

Promise.resolve().then(function() {
    return plugin.login(0, "1234567")
})
.then(function() {
    document.getElementById("pluginStatus").innerHTML = "<pre>" + "Token logged in" + "</pre>";
})
.catch( msg => {
    document.getElementById("pluginStatus").innerHTML = "<pre>" + msg + "</pre>";
})
.finally(
    function() {
        document.getElementById("pluginStatus").innerHTML = document.getElementById("pluginStatus").innerHTML + "<pre>" + "Finally" + "</pre>";
    }
);