[英]JavaScript to capture IP via WebRTC (issue with async/await)
I have came up with code that capture IPs via WebRTC. 我想出了通过WebRTC捕获IP的代码。 However I have run into issue, I can't return IPs as variable, I'm able only print IPs in console, show them in alert or show them on HTML page. 但是我遇到了问题,我无法将IP作为变量返回,我只能在控制台中打印IP,在警报中显示它们或在HTML页面上显示它们。 But I need return IPs as variable from function. 但是我需要从函数返回IP作为变量。
I believe issue is in async/awaiting. 我认为问题出在异步/等待中。 I'm not JavaScript developer and it will took whole day to find out a place where to put await
. 我不是JavaScript开发人员,需要一整天的时间才能找到可以await
的地方。
Please help me solve this issue. 请帮我解决这个问题。 Thank you. 谢谢。
function findIPsWithWebRTC() {
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}),
noop = function() {},
IPs = {},
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key;
function ipIterate(ip) {
if (!IPs[ip]) console.log('got ip: ', ip);
IPs[ip] = true;
}
pc.createDataChannel("");
pc.createOffer(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(ipIterate);
});
pc.setLocalDescription(sdp, noop, noop);
}, noop);
pc.onicecandidate = function(ice) {
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
};
console.log("ips: " + JSON.stringify(IPs));
return {
"source": "WebRTC",
"name": "IPs",
"value": JSON.stringify(IPs)
}
}
alert(findIPsWithWebRTC().value);
I can output IPs in console, but I can't return IPs as value from function. 我可以在控制台中输出IP,但不能从功能返回IP作为值。
findIPsWithWebRTC
can't return the IPs, because the IPs are provided to your code asynchronously. findIPsWithWebRTC
无法返回IP,因为IP是异步提供给您的代码的。 A synchronous function cannot return the result of an asynchronous process. 同步函数无法返回异步过程的结果。
Instead, your findIPsWithWebRTC
should return a promise , which will be fulfilled with the object your currently trying to return. 相反,您的findIPsWithWebRTC
应该返回一个promise ,这将通过您当前尝试返回的对象来实现。 It looks like you get the IPs in in onicecandidate
(or perhaps the callback to createOffer
?), so (see ***
): 看起来您在onicecandidate
(或者也许是createOffer
的回调?)中获得了IP,因此(请参阅***
):
function findIPsWithWebRTC() {
// *** Return a promise
return new Promise((resolve, reject) => {
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new myPeerConnection({iceServers: [{urls: "stun:stun.l.google.com:19302"}]}),
noop = function() {},
IPs = {},
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key;
function ipIterate(ip) {
if (!IPs[ip]) console.log('got ip: ', ip);
IPs[ip] = true;
}
pc.createDataChannel("");
pc.createOffer(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(ipIterate);
});
pc.setLocalDescription(sdp, noop, noop);
// *** Resolve the promise? Or see below.
resolve({
"source": "WebRTC",
"name": "IPs",
"value": JSON.stringify(IPs)
});
}, noop);
pc.onicecandidate = function(ice) {
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
// *** Resolve the promise? Or see above.
resolve({
"source": "WebRTC",
"name": "IPs",
"value": JSON.stringify(IPs)
});
};
});
}
Presumably there's also a way for this to fail. 大概还有一种失败的方法。 You'll want to call reject
in that case, so that the promise doesn't stay unsettled forever. 在这种情况下,您将需要打电话给reject
,这样诺言就不会永远保持不变。
Code using findIPsWithWebRTC
will need to handle the fact that it provides a promise. 使用findIPsWithWebRTC
代码将需要处理它提供承诺的事实。 You can either consume it within an async
function: 您可以在async
函数中使用它:
// In an `async` function
try {
const ipInfo = await findIPsWithWebRTC();
// ...use `ipInfo`...
} catch (error) {
// Handle/report error
}
...or in a non- async
function, use then
and catch
: ...或者在非async
函数中,使用then
和catch
:
findIPsWithWebRTC()
.then(ipInfo => {
// ...use `ipInfo`...
})
.catch(error => {
// Handle/report error
});
In both cases, if the function consuming the result isn't the top-level consumer, you would normally leave error handling to it. 在这两种情况下,如果使用结果的函数都不是顶级消费者,则通常会对其进行错误处理。 In the async
example, you'd do that by not having the try
/ catch
(rejections are automatically propagated to the caller). 在async
示例中,您可以通过不使用try
/ catch
做到这一点(拒绝会自动传播到调用方)。 In the non- async
example, you'd do it by returning the result of calling then
and not having catch
. 在非async
示例中,您可以通过返回then
且没有catch
的结果来实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.