Обещание функции синтаксического анализа xml2js (обещания ES6)

Я пытаюсь реорганизовать некоторый код узла, который представляет собой целую кучу обратных вызовов. Я подумал, что было бы неплохо попробовать promises для этой цели. Я пытаюсь преобразовать некоторую строку xml в json с помощью модуля узла xml2js. Исходный код был:

"use strict";

var xml2jsParser = require('xml2js').parseString;

var string = "<container><tag3>option3</tag3></container>";

xml2jsParser(string, function(err, result)
{
    console.log(result);
});

и это отображает:

{ container: { tag1: [ 'option1' ], tag2: [ 'option2' ], tag3: [ 'option3' ] } }

После первого ответа на этот вопрос Как мне преобразовать существующий API обратного вызова в промисы? Я попытался обернуть функцию xml2jsParser с помощью промисов следующим образом:

"use strict";

var xml2jsParser = require('xml2js').parseString;

function promisesParser(string)
{
    return new Promise(function(resolve, reject)
    {
        xml2jsParser(string, resolve);
    });
}

var string = "<container><tag3>option3</tag3></container>";

promisesParser(string).then(function(err, result){
    console.log(result);
});

Это отображает undefined через консоль вместо объекта json, как и ожидалось. Я не понимаю, почему это происходит, поскольку я смог успешно сделать то же самое с другими функциями. Я знаю, что нечто подобное может быть достигнуто с помощью функции обещания Bluebird, но я хотел бы сделать это на простом Javascript без каких-либо сторонних библиотек.


person Daniel Siguero    schedule 02.03.2016    source источник
comment
Используйте обратный вызов в стиле узла № 3, а не простой обратный вызов № 2 из этого ответа.   -  person Bergi    schedule 03.03.2016


Ответы (3)


Вам нужно будет обернуть его следующим образом:

return new Promise(function(resolve, reject)
{
    xml2jsParser(string, function(err, result){
         if(err){
             reject(err);
         }
         else {
             resolve(result);
         }
    });
});

Затем используйте его следующим образом:

promisesParser(string).then(function(result){
    console.log(result);
}).catch(function(err){
    //error here
});
person MinusFour    schedule 02.03.2016

Другим вариантом является использование собственного метода promisify модуля util, доступного на Узел 8.0:

const xml2js = require('xml2js');
const util = require('util');

xml2js.parseStringPromise = util.promisify(xml2js.parseString);

// await xml2js.parseStringPromise(.. your xml ..);
person Alex K    schedule 27.07.2018
comment
Или xml2js.Parser.prototype.parseStringPromise = util.promisify(xml2js.parseString);, если вы будете создавать отдельные парсеры. Или делать это непосредственно на экземпляре парсера. - person Brian J. Miller; 15.02.2019
comment
@BrianJ.Miller так даже лучше - person Alex K; 15.02.2019

Есть 2 проблемы...

  1. Вы должны решить со значением, если оно проходит... и отклонить с ошибкой, когда оно не работает

  2. Вам нужно добавить блок catch в цепочку обработки обещаний для отлова ошибок.

var xml2jsParser = require('xml2js').parseString;

function promisesParser(string)
{
    return new Promise(function(resolve, reject)
    {
        xml2jsParser(string, function(err, result) {
            if (err) {
                return reject(err);
             } else {
                return resolve(result);
             }
        });
    });
}

var string = "<container><tag3>option3</tag3></container>";

promisesParser(string)
.then(console.log)
.catch(console.log);
person Arun Sivasankaran    schedule 02.03.2016