javascript - Node.js Promise 只返回它应该返回的一小部分
问题描述
我有一个 Promise,它曾经等待接收完整的 JSON 字符串,但现在它只返回 JSON 字符串的一小部分。我目前正在使用 Shopify API 来创建客户,这就是响应字符串的样子:
{
"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
我拥有的 Promise 在一个函数中,该函数应该在继续之前等待结果,但是正如您所看到的,它由于某种原因严重切断了字符串。
从我第一次编写函数开始的过去 6 个月里,它一直没有问题。今天是它开始这样做的第一天。
这是函数(AWS Lambda 上的节点 8.10):
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);
解决方案
我认为问题在于您进行分块的方式。请求可能会逐个向您发送数据,因此您需要将代码更改为:
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();
});
};
推荐阅读
- java - 编写代码以从 URL 下载内容后,我在 Log 中没有得到任何输出
- mysql - 如何在 PHP/MySQL 中通过外键获取所有值?
- php - Magento 模块问题
- python - PySpark RDD过滤器错误从字符串到整数
- javascript - 表行数据未在 Javascript 中更新和删除
- jquery - 存储弹出窗口被点击的次数
- c++ - 将向量写入输出文件c ++
- python - 如何在 DJANGO 的函数中以同一视图保存和显示数据
- react-aad-msal - 使用 react-aad-msal 在登录期间保持用户状态的成语
- swiftui - SwiftUi ViewModel 未初始化所有存储的属性