我正在尝试了解节点中的Promises。我希望能够使用http.request作为承诺。这是我到目前为止所学到的。
我使用setTimeout设置了一个测试用例,如下所示:
var makePromise = (txt, milli) => {
return new Promise((resolve, reject) => {
setTimeout(() => { // fn(cb)
console.log("I promise to...")
resolve(txt)
}, milli)
});
}
var p = makePromise("Come Home", 3000);
var q = makePromise("Go Shopping", 1000);
var tasks = [p, q];
console.log("Start with ", tasks);
Promise.all(tasks).then((res) => {
console.log(res);
console.log("Finish");
})
这很好用。现在我认为我需要做的就是用适当的http.request替换setTimeout函数。但它似乎并不那么简单。
以下是目前的尝试。
var makePromise = (collection, item) => {
var options = {
method: "PUT",
port: 9000,
host: "localhost",
path: `/${collection}/item/${item.Label.itemUUID}`,
headers: {
"Accept": "application/json",
"Content-type": "application/json",
"Content-length": JSON.stringify(req.body).length
}
};
console.log(JSON.stringify(options));
var httpPromise = new Promise((resolve, reject) => {
var vot = http.request(options, (votResponse) => {
var responseBody = [];
votResponse.on('data', (chunk) => {
console.log(`Got ${chunk.length} ${chunk}`);
responseBody.push(chunk);
});
votResponse.on('end', () => {
console.log("End of http");
console.log("After web proxy like call - raw data: ", Buffer.concat(responseBody).toString());
responseBody.json = JSON.parse(Buffer.concat(responseBody).toString());
resolve(responseBody.json);
});
votResponse.on('error', (err) => {
reject(err);
});
})
vot.write(JSON.stringify(item));
vot.end();
});
return httpPromise;
};
我知道像“请求 - 承诺”这样的库可以提供帮助,但我希望在使用库之前更深入地了解本机操作。任何人都可以指出我可以采用这种方法吗?
调用代码如下所示:
var collection = req.params.collection;
var patchInstruction = req.body.patchInstruction;
switch (patchInstruction) {
case "CASCADE DELETE":
console.log("CASCADE DELETE on", collection, req.body.item);
var tasks = [req.body.item].concat(req.body.asSubject).concat(req.body.asObject);
tasks = tasks.map((e, i, a) => {
e.Item = "DELETED"
return makeDeletePromise(collection, e); // a promise to do the http PUT
});
console.log("WIP ", tasks);
Promise.all(tasks).then((res) => {
console.log("To client --> ",res);
res.send(res);
})
break;
default:
console.log("No path to ",patchInstruction);
res.send(409);
break;
}
对端口9000的调用永远不会发生。
答案 0 :(得分:0)
通过catch
电话结束承诺链总是一个好主意。否则,在承诺链中发生的任何错误都将被吞噬" - 你根本看不到它。
因此,只要有then
,就应该有catch
。
Promise.all(tasks).then((res) => {
console.log("To client --> ", res);
res.send(res);
}).catch((err) => console.log(err));
我相信,错误位于res.send(res)
附近,因为http res
被本地res
遮蔽了。这实际上是responseBody.json
,因此没有send
方法。