Redux Saga生成器执行疑问:调用后为何能执行多个yield语句?
Redux Saga workerSaga 多yield顺序执行问题解答
你对生成器yield的行为存在误解:yield的作用是暂停生成器执行,而非完全退出函数,生成器的执行上下文(内部变量、当前执行位置)会被完整保留,直到外部再次调用生成器返回的迭代器的next()方法,代码会从上次暂停的yield位置继续向后执行。
你可以用原生JS生成器验证这个特性:
function* testGenerator() { console.log("执行到第一个yield前"); const val1 = yield "第一个yield返回值"; console.log("第一个yield返回值是", val1); const val2 = yield "第二个yield返回值"; console.log("第二个yield返回值是", val2); } // 调用生成器函数仅返回迭代器,函数内部代码不会立刻执行 const gen = testGenerator(); // 第一次调用next,执行到第一个yield暂停 console.log(gen.next("传入第一个next的值")); // 输出:执行到第一个yield前 → {value: "第一个yield返回值", done: false} // 第二次调用next,从第一个yield之后继续执行,到第二个yield暂停 console.log(gen.next("传入第二个next的值")); // 输出:第一个yield返回值是 传入第二个next的值 → {value: "第二个yield返回值", done: false} // 第三次调用next,从第二个yield之后继续执行,直到函数结束 console.log(gen.next("传入第三个next的值")); // 输出:第二个yield返回值是 传入第三个next的值 → {value: undefined, done: true}
再回到你给出的Saga代码,之所以两个yield会依次执行,是Redux Saga内部的运行时引擎在驱动生成器迭代:
- 当workerSaga被触发时,Saga运行时首先会调用
workerSaga()拿到生成器迭代器 - 第一次调用迭代器的
next()方法,代码执行到第一个yield call(api.getData)暂停,Saga引擎拿到call副作用描述对象后,会执行对应的异步请求api.getData - 异步请求返回结果后,Saga引擎会调用
gen.next(请求结果),把结果作为第一个yield的返回值赋值给result变量,代码继续向后执行到第二个yield put(action(result))暂停 - Saga引擎拿到
put副作用描述对象后,执行dispatch对应action的操作,完成后再次调用gen.next(),此时生成器内代码全部执行完毕,整个workerSaga运行结束
内容的提问来源于stack exchange,提问作者Gambit2007
相关产品推荐
相关产品推荐

