【发布时间】:2020-08-27 13:08:00
【问题描述】:
看起来互联网上没有人描述类似的问题,并且类似的解决方案对我不起作用。 我正在尝试 scrape 网页,因此我为解析器创建了类,其中一种方法如下所示:
get chListUrl() {
return "http://www.teleman.pl/program-tv/stacje";
}
getChannels() {
var dict = {};
axios.get(this.chListUrl).then(function (response) {
var $ = cheerio.load(response.data);
var ile_jest_stacji = $('#stations-index a').length;
$('#stations-index a').each( (i,elem) => {
let href = $(elem).attr('href');
let kodstacji = href.replace(/\/program-tv\/stacje\//ig,'');
let nazwastacji = $(elem).text();
dict[nazwastacji]=kodstacji;
});
return dict;
}).catch(function (error) {
console.log(error);
return null;
}).finally(function() {
console.log("Koniec");
});
}
问题是getChannels 必须是间接异步的,因为它包含 axios BUT
let tm = new TM();
var a = tm.getChannels();
a 总是未定义的,它应该是字典!这种构造意味着“将 tm.getChannels() 的执行结果分配给变量”,因此应始终在整个函数结束后进行赋值。否则这样的语言语法是没有用的,因为你永远无法确定变量中存储的是什么值,而且这样的错误很难找到和调试。
var a = await tm.getChannels();
不工作 -> SyntaxError: await 仅在异步函数中有效(嗯?)
将异步添加到 getChannels() 不会改变任何事情。
将异步分配给 getChannels() 并从分配中删除“等待”返回 Promise{undefined}(嗯?)
将 async 放在 axios 之前没有任何改变,因为 .then() 已经处理了响应
将 return dict 更改为 return await dict 会给出另一个“等待仅在异步函数中有效”(嗯?axios 是异步的)
我为此苦苦思索了 2 周。 在 Swift 中,当完成处理程序中返回某些内容时,它会在适当的时候分配给变量,为什么 Promise 返回的内容不以相同的方式工作?
【问题讨论】:
-
Such construct means "assing to variable a result of execution of tm.getChannels()" so assignment should always be done AFTER whole function ends.- 它IS在整个函数结束后完成。您的getChannels()函数不会立即执行您传递给.then(...)的函数。您将此函数作为 Promise 的 回调 - 你告诉解释器,“当请求完成时运行此代码”,解释器保存代码 并且然后返回而不运行它。 -
axios 是 GetChannels 中的内部函数。 GetChannels 不返回任何应返回字典的承诺,因此,如果我理解正确,如果 Promises 无法返回值,则它们在 JavaScript 中是无用的:( ,多么可悲的故事
-
他们可以返回一个值。它们可以异步返回值,但不能同步。这远非无用。这意味着您可以在等待 HTTP 请求完成的同时继续执行代码。这意味着您可以同时启动多个 HTTP 请求。你只需要围绕这个新模式调整你的代码 -
getChannels()依赖于一个 HTTP 请求,所以它不能直接返回一个字典,你必须给它一个回调或者让它返回一个承诺。这对你来说是异步 javascript。
标签: javascript promise axios