我已经从learnyounode完成了这个练习,我正在尝试使用ES2015的承诺(或者如果它更容易,可以使用其他库)来重构它。我已经阅读了有关承诺的内容,我认为我理解它们是如何工作的,但我想知道是否可以在以下代码中使用它们以及如何实现它。
我的目标是让代码更易于阅读和理解,并且更好地理解流程中的承诺。
let http = require("http");
if (process.argv.length != 5) {
throw new Error("Please provide the 3 URLs as a command line arguments");
}
let urls = [];
let results = [];
let count = 0;
for (let i = 2; i < process.argv.length; i++) {
urls.push(process.argv[i]);
}
function httpGet(index) {
let url = urls[index];
let result = "";
http.get(url, res => {
res.on("data", data => {
result += data;
});
res.on('end', () => {
count += 1;
results[index] = result;
if (count === 3) {
results.forEach(function(result) {
console.log(result);
});
}
});
});
}
for (let i = 0; i < urls.length; i++) {
httpGet(i);
}
答案 0 :(得分:2)
您可以尝试这样的事情:
'use strict';
const http = require('http');
if (process.argv.length != 5) {
throw new Error('Please provide the 3 URLs as a command line arguments');
}
let urls = [];
for (let i = 2; i < process.argv.length; i++) {
urls.push(process.argv[i]);
}
function httpGet(url) {
let result = '';
return new Promise((resolve, reject) => {
http.get(url, function (res) {
res.on('error', err => {
reject(err);
});
res.on('data', data => {
result += data;
});
res.on('end', () => {
//You can do resolve(result) if you don't need the url.
resolve({url, result});
});
})
});
}
let promises = urls.map(url => httpGet(url));
Promise.all(promises)
.then(results => {
console.log(`All done. Results: ${results}`);
})
.catch(err => {
console.error(err);
});
&#13;
答案 1 :(得分:1)
你可以做这样的事情,但是你应该知道结果可能不会按照给定输入的顺序返回。
编辑:现在将按照给定的顺序输出数据。
Search: (>(\d)<)
Replace: $2$2$2
答案 2 :(得分:1)
虽然为了教育目的而自己实现所有的承诺逻辑可能是有用的,但应该注意的是,对于具有承诺支持的HTTP请求,有很好的模块,例如request-promise
:
每月下载量超过100万,它被广泛使用,并且是针对此类任务的经过测试的解决方案。我总是建议为任何实际工作使用经过良好测试的解决方案,而不是重新发明轮子。
现在,出于教育目的,我总是建议尽可能多地重新发明轮子。例如,请参阅此答案,了解将基于回调的代码转换为承诺的一些示例:
另请参阅此答案中的所有链接:
您可以使用回调和承诺找到很多相同代码的示例,以便您可以检查差异。
答案 3 :(得分:0)
Node的核心库的接口不是基于承诺的。但是,您可以使用一个简单的函数将接受Node样式回调的函数转换为返回promise的函数。自己写它可能是一个很好的练习。或者在npm找到它。此转换函数通常命名为promisify
。它的更高级版本需要一个对象并转换其所有方法。