Вариант 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 возвращать обещание. Конструктор Обещания принимает методы разрешения и отклонения в качестве лямбда-параметров (они будут снова использоваться в качестве обратных вызовов, но вместо объявления их как функции в родительском компоненте они являются частью Обещания. Вы можете использовать разрешение для передать данные обратно в родительский компонент и использовать 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.
}
Тогда родительский сервис будет использовать возвращенный обещание указать, что делать, когда обещание выполнено. Это делается с помощью вызова then и передачи двух лямбд (один для успешного сценария, другой для обработки ошибок)
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.
});
},
Я объяснил вам, что Вы нуждались, или эти два варианта действительно смутили вас больше? :) Пожалуйста, дайте мне знать.