javascript - Node.js 中的承诺链
问题描述
我的 promise-then 链似乎不会等待每个先前的 return 语句。
new Promise(function (resolve, reject) {
console.log("1");
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("2");
if (info.item) {
console.log("item exists, don't retry");
return (info);
}
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
return(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("3");
const http = require('http');
http.get('otherurl' + info.item, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
console.log("processed");
return (info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("4 " + info);
});
我希望我的输出是,例如:
1
2
3已
处理
4 [someinfo]
这是我得到的:
1
2
3
4 未定义 已
处理
似乎只有第一个 promise-then 异步发生。为什么第二个和第三个 then 语句不等待先前的返回?
解决方案
目前的代码是:
new Promise(function (resolve, reject) {
console.log("1");
return(http.ClientRequest)
}).then(function (info) {
console.log("2");
return(http.ClientRequest)
}).then(function (info) {
console.log("3");
resolve(http.ClientRequest)
}).then(function (info) {
console.log("4 " + info);
});
要使 Promise 链工作,需要部件return
的承诺then
。但是你return
的任何东西都then
被视为承诺。但在你的情况下
- 你没有返回任何东西。
- 如果你是返回,它来自回调,所以基本上它不会走出函数。如果你这样做,你将在你的下一个 then 链中
return http.get(...)
获得对象。http.ClientRequest
不是实际数据。
所以在你的情况下,一个粗略的方法是:承诺每个http
电话。
new Promise(function (resolve, reject) {
console.log("1");
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("2");
if (info.item) {
console.log("item exists, don't retry");
return (info);
}
return new Promise(function (resolve, reject) {
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
})
}).then(function (info) {
console.log("3");
return new Promise(function (resolve, reject) {
const http = require('http');
http.get('otherurl' + info.item, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
console.log("processed");
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
})
}).then(function (info) {
console.log("4 " + info);
});
注意:正如我所说,这是一种非常不优雅的做事方式,我建议使用基于 promise 的库,axios
或者使用async
library 而不是 promise。你也可以使用async-await
. 他们每个人都是更好的方法。
推荐阅读
- deepsecurity - Trend DSM V12 SAAS API 示例给出“无法建立新连接:[Errno 11001] getaddrinfo failed')': /api/policies”
- powershell - powershell 导出组成员资格多个职位
- azure - 在 Azure IoT Edge 中运行的容器能否访问监视器以可视化数据?
- graphql - 我可以在 AppSync 的嵌套类型中查询基于 SS 的对象吗
- javascript - 将数组值放入多个变量 Javascript
- angular - 获取 QuotaExceededError
- excel - 如果工作簿正在使用并被锁定以进行编辑,我如何跳过它?
- html - 如何创建重复的嵌套 div 彩虹是 CSS
- android - Mutablelivedata 可变实例大小问题
- vue.js - 组件属性在一个 Vuex 状态更改时重新评估