Node.js Promise возвращает лишь часть того, что он должен - PullRequest
0 голосов
/ 10 мая 2019

У меня есть Promise, который раньше ожидал получения полной строки JSON, но теперь он просто возвращает только часть строки JSON. В настоящее время я использую API-интерфейс Shopify для создания клиентов, и так должна выглядеть строка ответа:

{
  "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
    }
  }
}

Тем не менее, вот что я на самом деле получаю:

{"customer

Обещание, которое у меня есть, находится в функции, которая должна ожидать результата, прежде чем продолжить, но, как вы можете видеть, по какой-то причине оно сильно обрезает строку.

В течение последних 6 месяцев, с тех пор как я впервые написал функцию, она работала без проблем. Сегодня первый день, когда он начал это делать.

Вот функция (Узел 8.10 в AWS Lambda):

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();
    });

}

И эта функция, которая у меня есть, вызывает эту функцию:

const customer = await makeCall(path, method, data);

1 Ответ

1 голос
/ 10 мая 2019

Я думаю, проблема в том, как вы делаете чанкинг. По запросу возможно отправить вам данные по частям, поэтому вам нужно изменить код на:

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();
  });
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...