如何在nodejs路由器中使用Promise和yield?

时间:2017-01-04 11:02:58

标签: javascript node.js amazon-web-services

我尝试使用Amazon Products Api配置后端工厂以获取数据。

这是我在nodejs中执行的脚本:

var amazon = require('amazon-product-api');
var client = amazon.createClient({
    awsId: 'ID',
    awsSecret: 'sectret',
    awsTag: 'tag',
});

// SERVER
// var Promise = require('bluebird');
var koa = require('koa');
var router = require('koa-router')();

router.get('/node/:index', function* () {
    this.body = yield client.browseNodeLookup({
        browseNodeId: this.params.index,
    });
});

router.get('/', function* (ctx, next) {
    var node = yield client.browseNodeLookup({
        browseNodeId: 1063498,
    });
    this.body = node;
});

var app = koa();
app.use(router.routes()).use(router.allowedMethods());
app.listen(8005);

在前端,我使用bluebird.js的Promise.map()来映射亚马逊产品节点的数组。在函数的最后,我期望将Array中的链接(字符串)转换为对象(通过API获得)。 这是功能:

someFn(links) { // links is an array of node IDs
    return Promise.map(links, (link) => {
        var link = link;

        if (typeof link === "object" || level > 1) {
            return link;
        } else {
            return loadUrl({
                url: 'http://localhost:8005/node/'+link,
                action: 'json',
            }).then((res) => {
                if (isJSON(res)) {
                    return new Category(res); // transform string to object
                } else {
                    return link;
                }
            });
        }
    });
}

亚马逊允许最多10个查询,这就是为什么我需要运行该函数几次或循环它以获取数组中每个字符串的对象。

想法是等待后端的成功答案或重复查询(yield client.browseNodeLookup) 或者只是传递节点ID数组并获得每个节点ID的JSON。

我对nodejs服务器和路由配置没有太多经验,所以你能帮我配置一下吗?

1 个答案:

答案 0 :(得分:1)

我仍然没有找到使用后端执行任务的解决方案,但我已经更新了loadUrl函数。该函数自行运行,直到找到成功的答案:

function loadUrl(options) {
    var options = options;

    return new Promise((resolve, reject) => {
        $.post('/', options).done((result) => {
            if (result != 'Internal Server Error') {
                resolve(result);
            } else {
                (function run(x) {
                    var x = x || 0;
                    // 300 - calls limit
                    // for me 100 is enough
                    if (x <= 300) {
                        setTimeout(function() {
                            $.post('/', options).done((result) => {
                                if (result != 'Internal Server Error') {
                                    resolve(result);
                                } else {
                                    console.log('call', x);
                                    run(x+1);
                                }
                            });
                        }, 100);
                    } else {
                        resolve(result);
                    }
                })();
            }
        });
    });
}

据我所知,$ .post()有答案的时间限制,这就是我遇到问题的原因。数据是由后端工厂获得的,但是我的前端脚本还没准备好等待它并停止了。