Node.js Promise仅返回应有的一小部分

时间:2019-05-09 22:43:32

标签: javascript node.js aws-lambda

我有一个Promise,它曾经等待接收完整的JSON字符串,但是现在它仅返回JSON字符串的一小部分。我目前正在使用Shopify API创建客户,这就是响应字符串应该是这样的:

def check_time_until_logout
  @time_left = Devise.timeout_in.seconds - (Time.now.to_i - user_session["last_request_at"]).round
end

但是,这实际上是我要回来的:

{
  "customer": {
    "id": 1073339461,
    "email": "steve.lastnameson@example.com",
    "accepts_marketing": false,
    "created_at": "2019-04-18T15:42:33-04:00",
    "updated_at": "2019-04-18T15:42:33-04:00",
    "first_name": "Steve",
    "last_name": "Lastnameson",
    "orders_count": 0,
    "state": "disabled",
    "total_spent": "0.00",
    "last_order_id": null,
    "note": null,
    "verified_email": true,
    "multipass_identifier": null,
    "tax_exempt": false,
    "phone": "+15142546011",
    "tags": "",
    "last_order_name": null,
    "currency": "USD",
    "addresses": [
      {
        "id": 1053317291,
        "customer_id": 1073339461,
        "first_name": "Mother",
        "last_name": "Lastnameson",
        "company": null,
        "address1": "123 Oak St",
        "address2": null,
        "city": "Ottawa",
        "province": "Ontario",
        "country": "Canada",
        "zip": "123 ABC",
        "phone": "555-1212",
        "name": "Mother Lastnameson",
        "province_code": "ON",
        "country_code": "CA",
        "country_name": "Canada",
        "default": true
      }
    ],
    "accepts_marketing_updated_at": "2019-04-18T15:42:33-04:00",
    "marketing_opt_in_level": null,
    "admin_graphql_api_id": "gid://shopify/Customer/1073339461",
    "default_address": {
      "id": 1053317291,
      "customer_id": 1073339461,
      "first_name": "Mother",
      "last_name": "Lastnameson",
      "company": null,
      "address1": "123 Oak St",
      "address2": null,
      "city": "Ottawa",
      "province": "Ontario",
      "country": "Canada",
      "zip": "123 ABC",
      "phone": "555-1212",
      "name": "Mother Lastnameson",
      "province_code": "ON",
      "country_code": "CA",
      "country_name": "Canada",
      "default": true
    }
  }
}

我所承诺的功能应该在继续执行之前等待结果,但是如您所见,由于某种原因,它严重切断了字符串。

自我首次编写该函数以来的过去6个月中,它一直没有出现问题。今天是它开始这样做的第一天。

以下是函数(AWS Lambda上的Node 8.10):

{"customer

这是我调用上面函数的函数:

async function makeCall(path, method, data = '', again = true) {

    return new Promise((resolve, reject) => {
        const bearer = "Basic " + Buffer.from(shopKey + ":" + shopPass).toString('base64');
        const options = {
            host: shopURL,
            path: path,
            method: method,
            headers: {
                "Content-Type" : "application/json",
                "Authorization" : bearer
            }
        };


        const req = http.request(options, (res) => {


        });

        req.on('response', function(res){

            res.on('data', function(chunk){
                const body  = chunk.toString('utf8');
                console.log('chunk', chunk);
                console.log(body);
                resolve(JSON.parse(body));
            });

        });

        req.on('error', (e) => {
            if (again){
                setTimeout(makeCall(path, method, data, again = false), 3000);
            } else {
                reject(e.message);
            }

        });

        // send the request
        req.write(JSON.stringify(data));
        req.end();
    });

}

1 个答案:

答案 0 :(得分:1)

我认为问题在于您进行分块的方式。请求可能会逐段向您发送数据,因此您需要将代码更改为:

async function makeCall(path, method, data = '', again = true) {
  return new Promise((resolve, reject) => {
    const bearer = "Basic " + Buffer.from(shopKey + ":" + shopPass).toString('base64');
    const options = {
      host: shopURL,
      path: path,
      method: method,
      headers: {
        "Content-Type" : "application/json",
        "Authorization" : bearer
      }
    };

    let body = '';
    const req = http.request(options, (res) => {
      // Here we are potentially getting chunks of data that we are
      // adding to the main result "body"
      res.on('data', function(chunk){
        body += chunk;
      });
      // Once the request ends we can resolve with the result
      res.on('end', function() {
        resolve(JSON.parse(body));
      });
    });

    req.on('error', (e) => {
      if (again){
        // Updated so that it forwards on the response/error,
        // and only gets called after the timeout
        setTimeout(() => makeCall(path, method, data, false).then(resolve).catch(reject), 3000);
      } else {
        reject(e.message);
      }
    });

    // send the request
    req.write(JSON.stringify(data));
    req.end();
  });
};