0

所以我猜我在做一些根本错误的事情。当我第一次从浏览器上传图像时,会触发以下函数,但它只发生一次。所以下次我上传图像时,我看不到 watchFileReader 函数再次运行.. 发生这种情况很奇怪..因为我正在让其他 saga 函数按预期运行!有人可以告诉我我可能做错了什么吗?

export function* watchFileReader() {
  const action = yield take("DROP_FILE")
  console.log('action', action)
  let file = action.file[0];
  readFile(file, function(e) {
    sessionStorage.removeItem('img')
    console.log('alskdjfalsdjkf', e.target.result)
    sessionStorage.setItem('img', e.target.result)
  })
}

export const readFile = (file, callback) => {
  let reader = new FileReader()
  reader.onloadend = callback;
  reader.readAsDataURL(file)
}

export function* rootSaga() {
  yield [
    watchFileReader()
  ]
}
4

2 回答 2

1

生效只会产生一次。您可以将 watcher 代码粘贴在 while 循环中,也可以使用 redux-saga 中的takeEvery助手。

因为它是一个生成器函数,所以 saga 被暂停,直到动作被中间件捕获并再次产生,所以它不像你会有一堆无限循环在后台呼啸而过,占用 CPU。

我使用与许多文档相同的设计模式,即有一个“观察者”传奇/进程在循环上运行以采取每一个调度的动作,并触发一个工人传奇或真正繁重的进程。

TakeEvery(或 takeLatest,如果你只想获取最新的)就像一个永远运行的 while 循环,每次它得到它正在寻找的动作时,都会派生一个新的工人,这使它成为一个非阻塞操作。

export function* fileReaderWorker(action) {
  console.log('action', action)
  let file = action.file[0];
  readFile(file, function(e) {
    sessionStorage.removeItem('img')
    console.log('alskdjfalsdjkf', e.target.result)
    sessionStorage.setItem('img', e.target.result)
  })
}

export function* watchFileReader() {
  yield takeEvery("DROP_FILE", fileReaderWorker)
}
// or the loop version
// while (true) {
//  const action = yield take("DROP_FILE")
//  yield fork(fileReaderWorker, ...args.concat(action))
//}

export const readFile = (file, callback) => {
  let reader = new FileReader()
  reader.onloadend = callback;
  reader.readAsDataURL(file)
}

export function* rootSaga() {
  yield [
    watchFileReader()
  ]
}
于 2016-08-26T23:16:47.107 回答
0

删除第一个文件后,saga 生成器的状态function将暂停,即{done: false}. 要使状态保持活动状态,您可以将收益包装functioninfinite while loop

export function* watchFileReader() {
  while(true) {
   const action = yield take("DROP_FILE")
   console.log('action', action)
   let file = action.file[0];
   readFile(file, function(e) {
    sessionStorage.removeItem('img')
    console.log('alskdjfalsdjkf', e.target.result)
    sessionStorage.setItem('img', e.target.result)
  })
 }
}

或者利用 redux-saga 提供的 takeEvery 或takeLatest副作用。

于 2017-08-28T10:08:05.840 回答