How*_*ard 95 synchronization node.js
如果我需要按顺序调用3个http API,那么对于以下代码来说,这将是一个更好的替代方法:
http.get({ host: 'www.example.com', path: '/api_1.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_2.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_3.php' }, function(res) {
res.on('data', function(d) {
});
});
}
});
});
}
});
});
}
Run Code Online (Sandbox Code Playgroud)
Ray*_*nos 68
使用延迟类似Futures.
var sequence = Futures.sequence();
sequence
.then(function(next) {
http.get({}, next);
})
.then(function(next, res) {
res.on("data", next);
})
.then(function(next, d) {
http.get({}, next);
})
.then(function(next, res) {
...
})
Run Code Online (Sandbox Code Playgroud)
如果你需要通过范围,那么就做这样的事情
.then(function(next, d) {
http.get({}, function(res) {
next(res, d);
});
})
.then(function(next, res, d) { })
...
})
Run Code Online (Sandbox Code Playgroud)
Jos*_*osh 53
我也喜欢Raynos的解决方案,但我更喜欢不同的流控制库.
https://github.com/caolan/async
根据您是否需要每个后续函数的结果,我要么使用系列,并行或瀑布.
系列必须连续执行时,但在每个后续函数调用中不一定需要结果.
并行如果它们可以并行执行,则在每个并行函数期间不需要每个结果,并且在完成所有并行操作时需要回调.
瀑布如果你想在每个函数中变形结果并传递给下一个函数
endpoints =
[{ host: 'www.example.com', path: '/api_1.php' },
{ host: 'www.example.com', path: '/api_2.php' },
{ host: 'www.example.com', path: '/api_3.php' }];
async.mapSeries(endpoints, http.get, function(results){
// Array of results
});
Run Code Online (Sandbox Code Playgroud)
小智 33
您可以使用我的公共节点库执行此操作:
function get(url) {
return new (require('httpclient').HttpClient)({
method: 'GET',
url: url
}).finish().body.read().decodeToString();
}
var a = get('www.example.com/api_1.php'),
b = get('www.example.com/api_2.php'),
c = get('www.example.com/api_3.php');
Run Code Online (Sandbox Code Playgroud)
jem*_*oii 28
到目前为止,我发现和使用的最简单的是sync-request,它支持节点和浏览器!
var request = require('sync-request');
var res = request('GET', 'http://google.com');
console.log(res.body.toString('utf-8'));
Run Code Online (Sandbox Code Playgroud)
就是这样,没有疯狂的配置,没有复杂的lib安装,尽管它确实有一个lib回退.只是工作.我在这里尝试了其他的例子,当有很多额外的设置要做或安装不起作用时难倒!
同步请求使用的示例在您使用时不会很好res.getBody(),所有get body都接受编码并转换响应数据.只是做res.body.toString(encoding).
gen*_*nry 20
我将使用带有apis列表的递归函数
var APIs = [ '/api_1.php', '/api_2.php', '/api_3.php' ];
var host = 'www.example.com';
function callAPIs ( host, APIs ) {
var API = APIs.shift();
http.get({ host: host, path: API }, function(res) {
var body = '';
res.on('data', function (d) {
body += d;
});
res.on('end', function () {
if( APIs.length ) {
callAPIs ( host, APIs );
}
});
});
}
callAPIs( host, APIs );
Run Code Online (Sandbox Code Playgroud)
编辑:请求版本
var request = require('request');
var APIs = [ '/api_1.php', '/api_2.php', '/api_3.php' ];
var host = 'www.example.com';
var APIs = APIs.map(function (api) {
return 'http://' + host + api;
});
function callAPIs ( host, APIs ) {
var API = APIs.shift();
request(API, function(err, res, body) {
if( APIs.length ) {
callAPIs ( host, APIs );
}
});
}
callAPIs( host, APIs );
Run Code Online (Sandbox Code Playgroud)
编辑:请求/异步版本
var request = require('request');
var async = require('async');
var APIs = [ '/api_1.php', '/api_2.php', '/api_3.php' ];
var host = 'www.example.com';
var APIs = APIs.map(function (api) {
return 'http://' + host + api;
});
async.eachSeries(function (API, cb) {
request(API, function (err, res, body) {
cb(err);
});
}, function (err) {
//called when all done, or error occurs
});
Run Code Online (Sandbox Code Playgroud)
似乎这个问题的解决方案永无止境,这里还有一个:)
// do it once.
sync(fs, 'readFile')
// now use it anywhere in both sync or async ways.
var data = fs.readFile(__filename, 'utf8')
Run Code Online (Sandbox Code Playgroud)
http://alexeypetrushin.github.com/synchronize
另一种可能性是建立一个跟踪已完成任务的回调:
function onApiResults(requestId, response, results) {
requestsCompleted |= requestId;
switch(requestId) {
case REQUEST_API1:
...
[Call API2]
break;
case REQUEST_API2:
...
[Call API3]
break;
case REQUEST_API3:
...
break;
}
if(requestId == requestsNeeded)
response.end();
}
Run Code Online (Sandbox Code Playgroud)
然后只需为每个ID分配一个ID,您就可以在关闭连接之前设置必须完成哪些任务的要求.
const var REQUEST_API1 = 0x01;
const var REQUEST_API2 = 0x02;
const var REQUEST_API3 = 0x03;
const var requestsNeeded = REQUEST_API1 | REQUEST_API2 | REQUEST_API3;
Run Code Online (Sandbox Code Playgroud)
好吧,它不漂亮.这只是进行顺序调用的另一种方式.不幸的是NodeJS没有提供最基本的同步调用.但我理解异步性的诱惑是什么.
截至 2018 年,使用 ES6 模块和 Promises,我们可以编写这样的函数:
import { get } from 'http';
export const fetch = (url) => new Promise((resolve, reject) => {
get(url, (res) => {
let data = '';
res.on('end', () => resolve(data));
res.on('data', (buf) => data += buf.toString());
})
.on('error', e => reject(e));
});
Run Code Online (Sandbox Code Playgroud)
然后在另一个模块中
let data;
data = await fetch('http://www.example.com/api_1.php');
// do something with data...
data = await fetch('http://www.example.com/api_2.php');
// do something with data
data = await fetch('http://www.example.com/api_3.php');
// do something with data
Run Code Online (Sandbox Code Playgroud)
代码需要在异步上下文中执行(使用async关键字)
| 归档时间: |
|
| 查看次数: |
179788 次 |
| 最近记录: |