简体   繁体   English

在 API 调用返回后,Node.js 会做一些事情

[英]Node.js do something after API call has returned

I'm making a call to the Amazon product API using aws-lib npm package.我正在使用 aws-lib npm 包调用 Amazon 产品 API。 I'm trying to get the result of that call and then save that information into my database, the problem I keep running into is that if I make a call with lots of parameters when I try to set the result of the call to the product I get undefined because the API call hasn't been returned completely yet.我正在尝试获取该调用的结果,然后将该信息保存到我的数据库中,我一直遇到的问题是,如果我在尝试将调用结果设置为产品时使用大量参数进行调用我未定义是因为 API 调用尚未完全返回。 I've attempted to use callbacks and promises to make sure the API result is completely returned before I do anything else but I can't get it to work.我试图使用回调和承诺来确保在我做任何其他事情之前完全返回 API 结果,但我无法让它工作。

This the the current state of my code这是我的代码的当前状态

  var aws = require('aws-lib');
    var host = "http://webservices.amazon.co.uk/onca/xml"
    var prodAdvOptions = {
      host: "webservices.amazon.co.uk",
      region: "UK"
    };

// provide credentials 
var prodAdv = aws.createProdAdvClient(myKey, myPass, myId, prodAdvOptions);

.post(function(req, res) {

    // Options for the Amazon API
    var options = {
      ItemId: req.body.itemId,
      ResponseGroup: "OfferFull, ItemAttributes",
      Condition: "New",
      MerchantId: "Amazon"
    }
    getInfo(options, saveProduct, res);
}

  function getInfo(options, saveProduct, res){

    // Make call to the API
    prodAdv.call("ItemLookup", options, function(err, result) { 
       //create new product
       var product = new Product();
       product.name = result.name
       //assign lots more things to the product - these will return undefined which is the problem
       saveProduct(product);
    })
  };

function saveProduct(product){
  // save product to the database
};

This is the call to the API using aws-lib这是使用 aws-lib 调用 API

exports.init = init;

function init(genericAWSClient) {
  return createProdAdvClient;

  function createProdAdvClient(accessKeyId, secretAccessKey, associateTag, options) {
    options = options || {};
    var client = genericAWSClient({
      host: options.host || "ecs.amazonaws.com",
      path: options.path || "/onca/xml",
      accessKeyId: accessKeyId,
      secretAccessKey: secretAccessKey,
      secure: options.secure
    });

    return {
      client: client,
      call: call
    };

    function call(action, query, callback) {
      query["Operation"] = action
      query["Service"] = "AWSECommerceService"
      query["Version"] = options.version || '2009-10-01'
      query["AssociateTag"] = associateTag;
      query["Region"] = options.region || "US"
      return client.call(action, query, callback);
    }
  }
}

I think I'm not using callbacks correctly or need another one for assigning the result to the product but can't work out where I'm going wrong.我想我没有正确使用回调或需要另一个回调来将结果分配给产品,但无法弄清楚我哪里出错了。

Thanks for the help I've been banging my head against this for 2 days.感谢您的帮助,我已经为此苦恼了 2 天。

It might be easier to see what's going on initially without promises, then use promises after an understanding has been reached.可能更容易在没有承诺的情况下看到最初发生的事情,然后在达成理解后使用承诺。

One option for the flow of the program is:程序流程的一种选择是:

  1. POST request is made and post callback is called发出 POST 请求并调用post回调
  2. getInfo is called getInfo被调用
  3. prodAdv is called which is ansynchronous, which means a callback will have to be provided with what to do after the call to aws has completed. prodAdv被调用,它是异步的,这意味着必须为回调提供在对 aws 的调用完成后要做什么。
  4. in that callback saveProduct is called, another asynchronous function.在那个回调saveProduct被调用时,另一个异步函数。 saveProduct must register a callback so that you can perform some action when the call to the database has been completed. saveProduct必须注册一个回调,以便您可以在对数据库的调用完成后执行某些操作。
  5. In that callback issue res.send在那个回调问题res.send

   api.post('somePost', function(req, resp) {
       makeAWSCallAsync(params, function(err, awsRespProducts) {
          saveProductsAsync(awsRespProducts, function(err, dbResp) {
              // db call has been completed 
              resp.send();        
          });        
       });        
    });

This is very bare bones, and along the way errors should probably be checked.这是非常简单的骨头,一路上可能应该检查错误。 Once this is working, you could refactor to use promises, which would remove the nested callbacks.一旦这个工作,你可以重构使用承诺,这将删除嵌套的回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM