首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有可能将传奇迭代器转换为常规承诺?

是否有可能将传奇迭代器转换为常规承诺?
EN

Stack Overflow用户
提问于 2017-07-08 19:23:23
回答 1查看 729关注 0票数 1

我正在为keepassxc网络扩展构建抽象层。它使用redux-saga通道来使chrome消息传递看起来是同步的。它运行得出奇地好。不过,我想要完全抽象化还原-传奇,它的方式将看起来像正常的函数返回承诺。

tl;博士

KeePassXC浏览器将是浏览器扩展,允许从浏览器检索存储在KeePassXC应用程序中的密码。有两种可能的通信协议: HTTP和NativeClient。因此,我决定使用类型记录接口,根据通信协议的不同,将有两个类实现这个接口。

接口:

代码语言:javascript
复制
interface Keepass {
  getDatabaseHash(): Promise<string>;
  getCredentials(origin: string, formUrl: string): Promise<KeepassCredentials[]>;
  associate(): Promise<KeepassAssociation>;
  isAssociated(dbHash: string): Promise<boolean>;
}

首次实施表示HTTP通信协议使用的是基于承诺的取api,因此实现是直截了当的,并且100%符合这个接口。

第二次实施表示NativeClient协议是使用redux(效果和通道)使异步消息传递看起来像同步函数调用。这是有点复杂,但工作相当好,涵盖边缘情况,这将很难处理任何其他方式,因为本地消息传递是基于标准输入和标准输出流的协议,所以请求和响应可以交织,无序等……

我没有解决的实际问题是,第二个实现没有实现接口,因为它的生成器没有承诺。

主要想转换(包装)传奇迭代器功能和功能返回承诺。有一个很好的co库,基本上是为普通的生成器这样做的。但似乎不适用于复古传奇。

代码语言:javascript
复制
function* someGenerator() {
  const state = yield select(); // execution freeze here when called from wrapper
  const result = yield call(someEffect);
  return result;
}

function wrapper() {
  return co(someGenerator); // returns Promise
}

这有可能吗?如果是的话,我做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2017-07-10 14:58:59

Redux-saga是基于特殊原因的生成器函数--允许分离产生的部分并从位于内部saga进程管理器的一个端点管理它们。相反,在一般情况下,承诺是一种自我的东西,不能被部分地执行.换句话说,承诺管理它们所在的控制流,而生成器则由外部控制流管理。

当从包装器调用时,在这里生成select();//执行冻结

您的主要误解是假设select实际执行某些异步操作。不,它只是在这一点上暂停了函数somegenatator并将控制权转移到redux-saga引擎,后者知道这与返回值有关,并且可能在进程完成时状态异步进程(可能没有--没关系),saga引擎恢复生成器,并将返回值传递给它。

您可以在select (https://github.com/redux-saga/redux-saga/blob/master/src/internal/io.js#L139 )的源代码中轻松地看到它。它只是返回一个具有某种结构的对象,可以被saga引擎理解,然后引擎执行真正的操作,并以generatorName.next(resultValue)格式调用生成器。

UPD。纯理论上,你可以把它包装成可重新分配的承诺,但它是不可用的。

代码语言:javascript
复制
// Your library code

function deferredPromise() {
  let resolver = null;
  const promise = new Promise(resolve => (resolver = resolve));
  return [
    resolver,
    promise
  ];
}

function generateSomeGenerator() {

let [ selectDoneResolve, selectDonePromise ] = deferredPromise();

const someGenetator =  function* () {
  const state = yield select(); // execution freeze here when called from wrapper
  const [newSelectDoneResolve, newSelectDonePromise] = deferredPromise();
  selectDoneResolve({
    info: state, nextPromise: newSelectDonePromise
  });
  selectDoneResolve = newSelectDoneResolve;
  selectDonePromise = newSelectDonePromise;

  const result = yield call(someEffect);
  return result;
}

return {
  someGenetator,
  selectDonePromise
};

}

const { someGenetator: someGenetatorImpl, selectDonePromise } = generateSomeGenerator();

export const someGenetator = someGenetatorImpl;

// Wrapper for interface

selectDonePromise.then(watchDone)

function watchDone({ info, nextPromise }) {
   // Do something with your info
   nextPromise.then(watchDone);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44989971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档