2017-01-04 3 views
1

Я попытался настроить серверную фабрику для получения данных с помощью продуктов Amazon Api.Как использовать Promise с выходом в nodejs router?

Вот сценарий я исполняю в 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); 

В интерфейсе я использую Promise.map() по bluebird.js на карте массив узлов продукции Amazon. В финале функции я ожидаю преобразовать ссылки (строки) в массиве в объекты (полученные 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; 
       } 
      }); 
     } 
    }); 
} 

Amazon позволяет в максимально 10 запросов, поэтому мне нужно запустить функцию несколько раз или петли его, чтобы получить объект для каждой строки в массиве.

Идея состоит в том, чтобы дождаться успешного ответа на бэкэнд или повторить запрос (yield client.browseNodeLookup) Или просто передать массив идентификаторов узлов и получить JSON каждого из них в качестве результата.

У меня мало опыта с конфигурацией сервера nodeus и маршрутизацией, поэтому можете ли вы помочь мне настроить его правильно?

+0

Backend сценарий я думаю, может быть, как: Promise.map (this.params.index.split (''), функция (узел) { обратный выход client.browseNodeLookup ({ browseNodeId: this.params. index ( )) }), затем ((json) => { this.body = json; }) – Mike

ответ

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() имеет ограничение по времени для ответа, и вот почему у меня есть проблемы. Данные получены на бэкэндовом заводе, но мой внешний скрипт не был готов ждать его и был остановлен.

+0

И более того, я добавил к каждому Promise.map {параллелизм: 500} раньше). then ( – Mike

Смежные вопросы