如何在 redux-saga 中使用 chrome api

how to use chrome api in redux-saga

我正在尝试使用 redux-saga 制作 'get_current_url' func 顺便说一句,我一直在使用 React js 进行 chrome 扩展。 所以,我必须使用 chrome.tabs.query api 来获取当前的 uri 这是我的代码

import { Action } from "redux";
import { call, fork, put, takeEvery, takeLatest } from "redux-saga/effects";
import { all } from "redux-saga/effects";
import { timeActions } from "./timeSlice";

function getUrlApi() {
  const queryInfo = { active: true, currentWindow: true };
  let currentUrl: string = '';

  chrome.tabs.query(queryInfo, (tabs: chrome.tabs.Tab[]) => {
    const id = tabs[0].id;

    chrome.tabs.sendMessage(id || 0, "GET_URL", (res: any) => {
        console.log(res);           // ---> res.url will be receive data
        currentUrl = res.url;       // I wanna allocate this data to currentUrl and return but there is something kind of lexical problem
    })
  });
  return currentUrl;
}    

function* getUrl() {
  try {
    const test: string = yield getUrlApi();         // ---> always get undefined
    // yield timeActions.getUrlSuccess();
  } catch (err) {
    yield put(timeActions.getUrlFail(err));
  }
}

function* watchGetUrl() {
  yield takeLatest(timeActions.getUrl, getUrl);
}

export function* timeSaga() {
  yield all([fork(watchGetUrl)]);
}

如您所见,我正在尝试将 res.url 数据分配给 currentUrl; 但是,有一些词汇问题。 结果,它总是 return 未定义; 我怎么解决这个问题。谢谢

问题是 chrome api 函数是异步的,因此您在处理它们之前从函数返回。

chrome api 支持 promises,这在 sagas 中更容易处理,所以我建议改用它们。

async function getUrlApi() {
  const queryInfo = { active: true, currentWindow: true };

  const tabs = await chrome.tabs.query(queryInfo);
  const id = tabs[0].id;

  const res = await chrome.tabs.sendMessage(id || 0, "GET_URL");
  console.log(res);
  return res.url;
}