从promise对象(服务器端)获取值到客户端index.html

时间:2017-12-01 09:27:14

标签: javascript node.js express promise

我想知道如何将promise对象转换为字符串。 我正在调用一个API,它返回一个XML对象,使用axios和transform进行模板化。我的应用程序使用Express作为应用程序框架。我在promise中的.then中有一个console.log,它在命令行中返回控制台中的数据。

但是,当我想在index.html中处理这些数据时,我在控制台中收到了一个promise对象。我如何才能将promise对象中的'cover'部分转换为我的index.html?

服务器控制台日志记录: enter image description here

浏览器中的控制台记录: enter image description here

项目文件:

./路由/ index.js

router.get('/metadata', function(req,res,next){
    var info = metadata.getMetadataOnix(params);
    console.log('info:'+info);
    res.json({ test : info });
});

index.html,其中包含一个ajax get,用于调用document.ready

 $.get("/metadata", function(data){
      // call to metadata
});

metadata-onix.js - 我称之为api的文件

const axios = require('axios');
const transform = require('camaro');

exports.getMetadataOnix = function (id) {
    const template = {
        uitgever: '/Product/PublishingDetail/Publisher/PublisherName/text()',
        cover: "./Product/CollateralDetail/SupportingResource[ResourceContentType=01]/ResourceVersion/ResourceLink/text()"
    }

    return axios({
        method: 'get',
        url: 'https://someapi/getMetadataOnix/'+id,
        transformResponse: [function (data) {
            "use strict";
            data = transform(data, template);
            return data;
        }],
    }).catch(function(err){
        // log errors
        console.log('error:'+err);
    }).then(function(resp){
        var cover = '';
        cover = resp.data.cover;
        console.log('Cover from book:'+JSON.stringify(resp.data.cover));
        return cover;
    });
}

1 个答案:

答案 0 :(得分:5)

那里有一些问题。与您的问题相关的主要问题是,您错误地使用了getMetadataOnix的结果。它返回承诺,因此您必须使用该承诺。一种方法是通过then

router.get('/metadata', function(req,res,next){
    var info = metadata.getMetadataOnix('9789024576791').then(function(info) {
        console.log('info:'+info);
        res.json({ test : info });
    });
});

不要担心这意味着您的get回调会在您发送回复之前返回;这不是问题,Express专为此而设计。

另外,有两个关于错误处理的问题:

首先,您将拒绝转换为/ undefined的解决方案:

exports.getMetadataOnix = function (id) {
    // ...

    return axios({
        // ...
    }).catch(function(err){           // <===
        // log errors                 // <===
        console.log('error:'+err);    // <===
    }).then(function(resp){
        var cover = '';
        cover = resp.data.cover;
        console.log('Cover from book:'+JSON.stringify(resp.data.cover));
        return cover;
    });
}

请记住thencatch创建处理程序链,其中链中的每个步骤都会转换通过它的值。通过将.catch放在您所拥有的位置,您可以将拒绝转换为具有从catch处理程序返回的任何值的分辨率。由于您没有明确地返回一个,因此最终为undefined

由于您的then处理程序没有检查,因此当您尝试在其中使用resp.data.cover时,它会抛出错误,因为resp将{ {1}}。有趣的是,它将分辨率转换回拒绝(永远不会处理的)。

相反,根本不处理那里的错误。承诺规则之一是要么将承诺链返回给调用者,处理错误,而不是两者。 (您可能会将错误转换为其他类型的错误,但除非您能够解决问题,否则不要将其转换为分辨率。)

请在undefined回调中处理它。所以:

get

exports.getMetadataOnix = function (id) {
    const template = {
        uitgever: '/Product/PublishingDetail/Publisher/PublisherName/text()',
        cover: "./Product/CollateralDetail/SupportingResource[ResourceContentType=01]/ResourceVersion/ResourceLink/text()"
    }

    return axios({
        method: 'get',
        url: 'https://someapi/getMetadataOnix/'+id,
        transformResponse: [function (data) {
            "use strict";
            data = transform(data, template);
            return data;
        }],
    // No .catch here
    }).then(function(resp){
        var cover = '';
        cover = resp.data.cover;
        console.log('Cover from book:'+JSON.stringify(resp.data.cover));
        return cover;
    });
}