Многократный вызов узла API пользовательского поиска Google - PullRequest
0 голосов
/ 20 января 2020

Используя этот код в качестве ссылки, я попытался создать функцию, которая принимает слова в качестве входных данных, разбивает их на куски по 32 слова и возвращает список различных поисковых данных:

async function singleSearch(q, cx, auth) {
   const res = await customsearch.cse.list({
     cx: cx,
     q: q,
     auth: auth,
   });
   return res.data;
 };

function search(words, apikey=process.argv[2], engineid=process.argv[3]){
   const limit = 32; //32 word limit on google search
   var searchQueries = [];
   var len = Math.ceil(words.length/limit);
   for(var i = 0; i < len; i++){
       searchQueries.push( words.slice(i*limit, (i+1)*limit).join(" ") )
   };
   var searches = []
   for(var i = 0; i < searchQueries.length; i++){
       searches.push(singleSearch(searchQueries[i], engineid, apikey).catch(console.error))
   };
   return searches
   }

a = search("Do I understand it correctly that anotherCall() will be called only when someCall() is completed? What is the most elegant way of calling them in parallel?".split(" "));
console.log(a)

Этот подход не работает и возвращает Promise { <pending> }, и независимо от того, сколько await/async или Promise.all() я пробую, я не могу заставить его работать. Как правильно вызывать API в этом случае?

Ожидаемый результат:

[
    {
  kind: 'customsearch#search',
  url: {
    type: 'application/json',
    template: 'https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json'},
    ...
 },
...
]

Ответы [ 2 ]

0 голосов
/ 20 января 2020

Проблема в том, что вы пытаетесь выполнить асинхронность в l oop, которая не работает так, как вы ожидаете. Вам нужно либо использовать Promise.all, либо использовать for..of l oop с ожиданием. Вы можете сделать Promise.all так, как это.

async function singleSearch(q, cx, auth) {
  const res = await customsearch.cse.list({
    "cx": cx,
    "q": q,
    "auth": auth
  });
  return res.data;
}

function search(words, apikey = process.argv[2], engineid = process.argv[3]) {
  const limit = 32; // 32 word limit on google search
  const searchQueries = [];
  const len = Math.ceil(words.length / limit);
  for (var i = 0; i < len; i++) {
    searchQueries.push(words.slice(i * limit, (i + 1) * limit).join(" "));
  }

  return Promise.all(searchQueries.map(query => {
    return singleSearch(query, engineid, apikey).catch(console.error);
  }));
}

(async () => {
  const a = await search("Do I understand it correctly that anotherCall() will be called only when someCall() is completed? What is the most elegant way of calling them in parallel?".split(" "));
  console.log(a);
})();


0 голосов
/ 20 января 2020

Поскольку функция singleSearch asyn c возвращает обещание, вам нужно использовать then, чтобы получить результат поиска, а затем вывести pu sh в массив searches.

searches.push(singleSearch(searchQueries[i], engineid, apikey).catch(console.error))

Оформить заказ этот ответ на Stackoverflow.

...