我知道有人问过类似的问题,我试着理解它们,并将其应用到我自己的问题上,但我还没有能够使任何事情生效。
下面的代码是Adonis.js控制器中的一个函数。
它应该获取一个搜索项,并使用Google search API (serpApi)来搜索该搜索项,然后返回一个URL数组。
但是,目前我只能让它链接‘console.log’,但是每当调用'googleSearch‘函数时,我都想返回一个链接数组。
async googleSearch(searchTerm) {
let client = new GSR.GoogleSearchResults("[MyApiKey]")
var parameter = {
q: `${searchTerm}`,
hl: "en",
gl: "us",
google_domain: "google.com",
};
const callback = function(data) {
let links = [];
for (let i = 0; i < data.organic_results.length; i++) {
links.push(data.organic_results[i].link)
}
console.log(links)
}
client.json(parameter, callback)
}当我从回调函数中进行控制台日志时,我可以看到我需要的数据,但是,我希望在调用父函数时返回这些数据,而不是将其记录到控制台。
我知道问题出在异步/同步区域的某个地方,我试着想办法重新组织回调并改变事情的顺序,尽我所知,但我似乎不能让它工作。
下面是我试图实现的一个例子,显然它不起作用,但它可能有助于澄清一些事情。
async googleSearch(searchTerm) {
let results= []
let client = new GSR.GoogleSearchResults("[MyApiKey]")
var parameter = {
q: `${searchTerm}`,
hl: "en",
gl: "us",
google_domain: "google.com",
};
const callback = await function(data) {
let links = [];
for (let i = 0; i < data.organic_results.length; i++) {
links.push(data.organic_results[i].link)
}
results.push(links)
}
client.json(parameter, callback)
return results
}发布于 2020-04-29 00:32:41
变体1。
试着改变“等到”的心态,最好把它想成“当你做完了告诉我”。
假设您的方法googleSearch有第二个参数,该参数将是您的父(调用)组件提供的函数。此函数将仅在当前回调中调用,而不是在console.log(链接)中调用。这样,调用组件不会等到接收到带有链接的结果,而是在链接准备就绪时,父组件将接收到对所提供函数的异步调用,它们将作为参数传递。因此,让我们将该函数称为“processLinks”。
googleSearch(searchTerm, processLinks) {
let client = new GSR.GoogleSearchResults("[MyApiKey]")
var parameter = {
q: `${searchTerm}`,
hl: "en",
gl: "us",
google_domain: "google.com",
};
const callback = function(data) {
let links = [];
for (let i = 0; i < data.organic_results.length; i++) {
links.push(data.organic_results[i].link)
}
processLinks(links)
}
client.json(parameter, callback)
}然后父组件将调用类似如下的内容:
onSearchTermChange(searchTerm){
childComponent.googleSearch(searchTerm, this.processLinks);
},
processLinks(links){
// Do whatever needed with the links.
}变体2。
上层解决方案是一种实现自己的承诺机制(不是很酷,只是为了帮助你理解原则)。因此,第二个变体不是添加一个processLinks函数作为参数,而是让googleSearch返回一个promise。Promise的构造函数接受resolve和reject方法作为lambda参数(它们将再次用作回调,但它们不是在父组件中声明为函数,而是作为Promise的一部分。您可以使用resolve将数据传递回父组件,并在出现错误时使用reject,父组件不应再等待结果。让我们用一个例子来尝试一下:
googleSearch(searchTerm) {
return new Promise ((resolve, reject) => {
let client = new GSR.GoogleSearchResults("[MyApiKey]")
var parameter = {
q: `${searchTerm}`,
hl: "en",
gl: "us",
google_domain: "google.com",
};
const callback = function(data) {
let links = [];
for (let i = 0; i < data.organic_results.length; i++) {
links.push(data.organic_results[i].link)
}
resolve(links)
}
client.json(parameter, callback) // TODO If this fails call reject(errorDetails);
}); // The promise returned.
}然后,父服务将使用返回的promise来指定解析promise时要执行的操作。这是通过调用'then‘并传递两个lambda来完成的(一个用于成功场景,一个用于错误处理)
onSearchTermChange(searchTerm){
childComponent.googleSearch(searchTerm, this.processLinks).then((links) => {
// Here we are when the child component invoked 'resolve(links)'
}, (error) => {
// Well in upper example I dont use the error handled (and should). You can add it for example if your call to client.json fails for some reason.
});
},我有没有向你解释过你需要什么,或者这两个变体实际上让你更困惑了?:)请让我知道。
https://stackoverflow.com/questions/61483434
复制相似问题