异步 Soup 调用
Asynchronous Soup calls
我正在为 Gnome DE 开发简单的扩展,但在处理异步 Soup 调用和事件循环时遇到了一些麻烦。
这是我的:
_httpSession = new Soup.Session();
let token = 'sometoken'
let url = 'someurl';
let _allData = [];
let elements = [1,2];
for (let el of elements) {
let message = Soup.form_request_new_from_hash('GET', url + el, { access_token: token });
_httpSession.queue_message(message, () => {
if (message.status_code != Soup.KnownStatusCode.OK) {
_error(message.status_code.toString());
}
try {
message = JSON.parse(message.response_body.data).items;
} catch (e) {
_error(e.toString());
}
_allData = _allData.concat([el, message]);
});
}
鉴于上述for循环中的异步调用,如何确保_allData.concat()已在所有迭代中执行?我想打印出 _allData 变量,但仅当每个 el 的连接被执行时。
最简单的方法可能是异步等待模式:
// Your request function can be turned into a Promise:
function requestFunc(session, message) {
return new Promise((resolve, reject) => {
session.queue_message(message, () => {
try {
if (message.status_code === Soup.KnownStatusCode.OK) {
let result = JSON.parse(message.response_body.data);
resolve(result);
} else {
reject(new Error(message.status_code.toString()));
}
} catch (e) {
reject(e);
}
});
});
}
// Then you can await each in a loop
async function logRequestResults(session, url, token, elements) {
try {
let results = [];
for (let el of elements) {
let message = Soup.form_request_new_from_hash('GET', url + el, {
access_token: token
});
let result = await requestFunc(session, message);
results = results.concat([el, results.items]);
}
// Success; all requests completed
log(results);
} catch (e) {
// An error occurred somewhere in the loop
logError(e);
}
}
// Using the function
_httpSession = new Soup.Session();
let token = 'sometoken'
let url = 'someurl';
let elements = [1,2];
logRequestResults(session, url, token, elements);
根据您实际对结果执行的操作,您可能需要对其进行重构。重要的部分是将 func(something, () => {})
模式变成
Promise
你可以 await
循环。
另请注意,async
隐含函数 return 和 Promise
,那些也可以与 await
一起使用。
我正在为 Gnome DE 开发简单的扩展,但在处理异步 Soup 调用和事件循环时遇到了一些麻烦。
这是我的:
_httpSession = new Soup.Session();
let token = 'sometoken'
let url = 'someurl';
let _allData = [];
let elements = [1,2];
for (let el of elements) {
let message = Soup.form_request_new_from_hash('GET', url + el, { access_token: token });
_httpSession.queue_message(message, () => {
if (message.status_code != Soup.KnownStatusCode.OK) {
_error(message.status_code.toString());
}
try {
message = JSON.parse(message.response_body.data).items;
} catch (e) {
_error(e.toString());
}
_allData = _allData.concat([el, message]);
});
}
鉴于上述for循环中的异步调用,如何确保_allData.concat()已在所有迭代中执行?我想打印出 _allData 变量,但仅当每个 el 的连接被执行时。
最简单的方法可能是异步等待模式:
// Your request function can be turned into a Promise:
function requestFunc(session, message) {
return new Promise((resolve, reject) => {
session.queue_message(message, () => {
try {
if (message.status_code === Soup.KnownStatusCode.OK) {
let result = JSON.parse(message.response_body.data);
resolve(result);
} else {
reject(new Error(message.status_code.toString()));
}
} catch (e) {
reject(e);
}
});
});
}
// Then you can await each in a loop
async function logRequestResults(session, url, token, elements) {
try {
let results = [];
for (let el of elements) {
let message = Soup.form_request_new_from_hash('GET', url + el, {
access_token: token
});
let result = await requestFunc(session, message);
results = results.concat([el, results.items]);
}
// Success; all requests completed
log(results);
} catch (e) {
// An error occurred somewhere in the loop
logError(e);
}
}
// Using the function
_httpSession = new Soup.Session();
let token = 'sometoken'
let url = 'someurl';
let elements = [1,2];
logRequestResults(session, url, token, elements);
根据您实际对结果执行的操作,您可能需要对其进行重构。重要的部分是将 func(something, () => {})
模式变成
Promise
你可以 await
循环。
另请注意,async
隐含函数 return 和 Promise
,那些也可以与 await
一起使用。