Should I always use redux-saga `call` effect for functions that return promise?












1















Assuming I have a function



function* request(url) {
return global.fetch(url).then(response =>
_.result(response, 'json'))
}


Both code examples work fine to me



const {data} = yield call(request, 'http://example.com/api');
yield put(actionSuccess(data));


and



const {data} = yield request('http://example.com/api');
yield put(actionSuccess(data));


Therefore the question. What is an advantage of using the call effect for functions that return promises?










share|improve this question





























    1















    Assuming I have a function



    function* request(url) {
    return global.fetch(url).then(response =>
    _.result(response, 'json'))
    }


    Both code examples work fine to me



    const {data} = yield call(request, 'http://example.com/api');
    yield put(actionSuccess(data));


    and



    const {data} = yield request('http://example.com/api');
    yield put(actionSuccess(data));


    Therefore the question. What is an advantage of using the call effect for functions that return promises?










    share|improve this question



























      1












      1








      1








      Assuming I have a function



      function* request(url) {
      return global.fetch(url).then(response =>
      _.result(response, 'json'))
      }


      Both code examples work fine to me



      const {data} = yield call(request, 'http://example.com/api');
      yield put(actionSuccess(data));


      and



      const {data} = yield request('http://example.com/api');
      yield put(actionSuccess(data));


      Therefore the question. What is an advantage of using the call effect for functions that return promises?










      share|improve this question
















      Assuming I have a function



      function* request(url) {
      return global.fetch(url).then(response =>
      _.result(response, 'json'))
      }


      Both code examples work fine to me



      const {data} = yield call(request, 'http://example.com/api');
      yield put(actionSuccess(data));


      and



      const {data} = yield request('http://example.com/api');
      yield put(actionSuccess(data));


      Therefore the question. What is an advantage of using the call effect for functions that return promises?







      javascript asynchronous redux-saga






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 24 '18 at 23:05







      Eugene Tiutiunnyk

















      asked Nov 24 '18 at 23:00









      Eugene TiutiunnykEugene Tiutiunnyk

      101210




      101210
























          2 Answers
          2






          active

          oldest

          votes


















          2














          Some benefits of using call():





          1. Testability, the only benefit the docs seem to mention (lower half of the page).

          2. More fine-grained task cancellation. Sagas are ES6 generators, which only yield control (back to redux-saga middleware) when you use the yield statement. These are the only points where cancellation can happen. A yield call() gives redux-saga an opportunity to cancel the task right before it's about to make that no longer needed call. Task cancellation is performed using gen.return() generator method. [1] [2]

          3. More fine-grained task scheduling in general. Redux-saga's concurrency model is basically cooperative multitasking. And JavaScript is single-threaded. A So when you yield, it's the only opportunity for redux-saga middleware to do any kind of scheduling other tasks. (I'm not sure how good redux-saga is at this, though.)


          For more information, I think it's best to open an issue on redux-saga's Github to ask the maintainer directly.






          share|improve this answer





















          • 1





            Yeah, makes sense only if unit tests runner walks through saga generator step by step. Although if SagaTester approach is used, when a saga is executed natively during unit test, having call doesn't bring any value.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 17:50



















          1














          The advantage is visibility into what is going on in the app.



          You want to know when, why and how the state is updated [1].



          call [2] triggers an effect when a saga monitor is configured on the saga middleware before running the effect and after the effect is resolved.



          With a saga monitor configured and without using call effect, I see this in the monitor logs.



          Without call



          However with call effect,



          With call






          share|improve this answer


























          • Using yield request will make sure that the promise is canceled if the parent saga is canceled. I went through debugging and got my breakpoint stoped in resolvePromise of redux-saga.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 0:49











          • I used "saga-monitor" to see if there is any difference in the debug trace information we get from using or not using call. In fact, there is almost no difference. This is the trace line with using call: effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: request} and this is without effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: {...}} Basically, I am losing the request function name in logs, but it could be sacrificed due to increased code readability.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 1:11











          • Thanks for your feedback. You're correct that the put is used for dispatch actions to store. Other effects are sent to the saga middleware. I took a look using the saga-monitor-example and yes, the function name is unknown in the log. I'll update my answer to reflect my current findings about this matter.

            – Oluwafemi Sule
            Nov 25 '18 at 12:37











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463114%2fshould-i-always-use-redux-saga-call-effect-for-functions-that-return-promise%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          Some benefits of using call():





          1. Testability, the only benefit the docs seem to mention (lower half of the page).

          2. More fine-grained task cancellation. Sagas are ES6 generators, which only yield control (back to redux-saga middleware) when you use the yield statement. These are the only points where cancellation can happen. A yield call() gives redux-saga an opportunity to cancel the task right before it's about to make that no longer needed call. Task cancellation is performed using gen.return() generator method. [1] [2]

          3. More fine-grained task scheduling in general. Redux-saga's concurrency model is basically cooperative multitasking. And JavaScript is single-threaded. A So when you yield, it's the only opportunity for redux-saga middleware to do any kind of scheduling other tasks. (I'm not sure how good redux-saga is at this, though.)


          For more information, I think it's best to open an issue on redux-saga's Github to ask the maintainer directly.






          share|improve this answer





















          • 1





            Yeah, makes sense only if unit tests runner walks through saga generator step by step. Although if SagaTester approach is used, when a saga is executed natively during unit test, having call doesn't bring any value.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 17:50
















          2














          Some benefits of using call():





          1. Testability, the only benefit the docs seem to mention (lower half of the page).

          2. More fine-grained task cancellation. Sagas are ES6 generators, which only yield control (back to redux-saga middleware) when you use the yield statement. These are the only points where cancellation can happen. A yield call() gives redux-saga an opportunity to cancel the task right before it's about to make that no longer needed call. Task cancellation is performed using gen.return() generator method. [1] [2]

          3. More fine-grained task scheduling in general. Redux-saga's concurrency model is basically cooperative multitasking. And JavaScript is single-threaded. A So when you yield, it's the only opportunity for redux-saga middleware to do any kind of scheduling other tasks. (I'm not sure how good redux-saga is at this, though.)


          For more information, I think it's best to open an issue on redux-saga's Github to ask the maintainer directly.






          share|improve this answer





















          • 1





            Yeah, makes sense only if unit tests runner walks through saga generator step by step. Although if SagaTester approach is used, when a saga is executed natively during unit test, having call doesn't bring any value.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 17:50














          2












          2








          2







          Some benefits of using call():





          1. Testability, the only benefit the docs seem to mention (lower half of the page).

          2. More fine-grained task cancellation. Sagas are ES6 generators, which only yield control (back to redux-saga middleware) when you use the yield statement. These are the only points where cancellation can happen. A yield call() gives redux-saga an opportunity to cancel the task right before it's about to make that no longer needed call. Task cancellation is performed using gen.return() generator method. [1] [2]

          3. More fine-grained task scheduling in general. Redux-saga's concurrency model is basically cooperative multitasking. And JavaScript is single-threaded. A So when you yield, it's the only opportunity for redux-saga middleware to do any kind of scheduling other tasks. (I'm not sure how good redux-saga is at this, though.)


          For more information, I think it's best to open an issue on redux-saga's Github to ask the maintainer directly.






          share|improve this answer















          Some benefits of using call():





          1. Testability, the only benefit the docs seem to mention (lower half of the page).

          2. More fine-grained task cancellation. Sagas are ES6 generators, which only yield control (back to redux-saga middleware) when you use the yield statement. These are the only points where cancellation can happen. A yield call() gives redux-saga an opportunity to cancel the task right before it's about to make that no longer needed call. Task cancellation is performed using gen.return() generator method. [1] [2]

          3. More fine-grained task scheduling in general. Redux-saga's concurrency model is basically cooperative multitasking. And JavaScript is single-threaded. A So when you yield, it's the only opportunity for redux-saga middleware to do any kind of scheduling other tasks. (I'm not sure how good redux-saga is at this, though.)


          For more information, I think it's best to open an issue on redux-saga's Github to ask the maintainer directly.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 28 '18 at 18:15

























          answered Nov 25 '18 at 14:07









          Andrey MoiseevAndrey Moiseev

          1,60552946




          1,60552946








          • 1





            Yeah, makes sense only if unit tests runner walks through saga generator step by step. Although if SagaTester approach is used, when a saga is executed natively during unit test, having call doesn't bring any value.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 17:50














          • 1





            Yeah, makes sense only if unit tests runner walks through saga generator step by step. Although if SagaTester approach is used, when a saga is executed natively during unit test, having call doesn't bring any value.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 17:50








          1




          1





          Yeah, makes sense only if unit tests runner walks through saga generator step by step. Although if SagaTester approach is used, when a saga is executed natively during unit test, having call doesn't bring any value.

          – Eugene Tiutiunnyk
          Nov 25 '18 at 17:50





          Yeah, makes sense only if unit tests runner walks through saga generator step by step. Although if SagaTester approach is used, when a saga is executed natively during unit test, having call doesn't bring any value.

          – Eugene Tiutiunnyk
          Nov 25 '18 at 17:50













          1














          The advantage is visibility into what is going on in the app.



          You want to know when, why and how the state is updated [1].



          call [2] triggers an effect when a saga monitor is configured on the saga middleware before running the effect and after the effect is resolved.



          With a saga monitor configured and without using call effect, I see this in the monitor logs.



          Without call



          However with call effect,



          With call






          share|improve this answer


























          • Using yield request will make sure that the promise is canceled if the parent saga is canceled. I went through debugging and got my breakpoint stoped in resolvePromise of redux-saga.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 0:49











          • I used "saga-monitor" to see if there is any difference in the debug trace information we get from using or not using call. In fact, there is almost no difference. This is the trace line with using call: effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: request} and this is without effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: {...}} Basically, I am losing the request function name in logs, but it could be sacrificed due to increased code readability.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 1:11











          • Thanks for your feedback. You're correct that the put is used for dispatch actions to store. Other effects are sent to the saga middleware. I took a look using the saga-monitor-example and yes, the function name is unknown in the log. I'll update my answer to reflect my current findings about this matter.

            – Oluwafemi Sule
            Nov 25 '18 at 12:37
















          1














          The advantage is visibility into what is going on in the app.



          You want to know when, why and how the state is updated [1].



          call [2] triggers an effect when a saga monitor is configured on the saga middleware before running the effect and after the effect is resolved.



          With a saga monitor configured and without using call effect, I see this in the monitor logs.



          Without call



          However with call effect,



          With call






          share|improve this answer


























          • Using yield request will make sure that the promise is canceled if the parent saga is canceled. I went through debugging and got my breakpoint stoped in resolvePromise of redux-saga.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 0:49











          • I used "saga-monitor" to see if there is any difference in the debug trace information we get from using or not using call. In fact, there is almost no difference. This is the trace line with using call: effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: request} and this is without effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: {...}} Basically, I am losing the request function name in logs, but it could be sacrificed due to increased code readability.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 1:11











          • Thanks for your feedback. You're correct that the put is used for dispatch actions to store. Other effects are sent to the saga middleware. I took a look using the saga-monitor-example and yes, the function name is unknown in the log. I'll update my answer to reflect my current findings about this matter.

            – Oluwafemi Sule
            Nov 25 '18 at 12:37














          1












          1








          1







          The advantage is visibility into what is going on in the app.



          You want to know when, why and how the state is updated [1].



          call [2] triggers an effect when a saga monitor is configured on the saga middleware before running the effect and after the effect is resolved.



          With a saga monitor configured and without using call effect, I see this in the monitor logs.



          Without call



          However with call effect,



          With call






          share|improve this answer















          The advantage is visibility into what is going on in the app.



          You want to know when, why and how the state is updated [1].



          call [2] triggers an effect when a saga monitor is configured on the saga middleware before running the effect and after the effect is resolved.



          With a saga monitor configured and without using call effect, I see this in the monitor logs.



          Without call



          However with call effect,



          With call







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 25 '18 at 12:52

























          answered Nov 24 '18 at 23:40









          Oluwafemi SuleOluwafemi Sule

          12.1k1532




          12.1k1532













          • Using yield request will make sure that the promise is canceled if the parent saga is canceled. I went through debugging and got my breakpoint stoped in resolvePromise of redux-saga.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 0:49











          • I used "saga-monitor" to see if there is any difference in the debug trace information we get from using or not using call. In fact, there is almost no difference. This is the trace line with using call: effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: request} and this is without effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: {...}} Basically, I am losing the request function name in logs, but it could be sacrificed due to increased code readability.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 1:11











          • Thanks for your feedback. You're correct that the put is used for dispatch actions to store. Other effects are sent to the saga middleware. I took a look using the saga-monitor-example and yes, the function name is unknown in the log. I'll update my answer to reflect my current findings about this matter.

            – Oluwafemi Sule
            Nov 25 '18 at 12:37



















          • Using yield request will make sure that the promise is canceled if the parent saga is canceled. I went through debugging and got my breakpoint stoped in resolvePromise of redux-saga.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 0:49











          • I used "saga-monitor" to see if there is any difference in the debug trace information we get from using or not using call. In fact, there is almost no difference. This is the trace line with using call: effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: request} and this is without effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: {...}} Basically, I am losing the request function name in logs, but it could be sacrificed due to increased code readability.

            – Eugene Tiutiunnyk
            Nov 25 '18 at 1:11











          • Thanks for your feedback. You're correct that the put is used for dispatch actions to store. Other effects are sent to the saga middleware. I took a look using the saga-monitor-example and yes, the function name is unknown in the log. I'll update my answer to reflect my current findings about this matter.

            – Oluwafemi Sule
            Nov 25 '18 at 12:37

















          Using yield request will make sure that the promise is canceled if the parent saga is canceled. I went through debugging and got my breakpoint stoped in resolvePromise of redux-saga.

          – Eugene Tiutiunnyk
          Nov 25 '18 at 0:49





          Using yield request will make sure that the promise is canceled if the parent saga is canceled. I went through debugging and got my breakpoint stoped in resolvePromise of redux-saga.

          – Eugene Tiutiunnyk
          Nov 25 '18 at 0:49













          I used "saga-monitor" to see if there is any difference in the debug trace information we get from using or not using call. In fact, there is almost no difference. This is the trace line with using call: effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: request} and this is without effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: {...}} Basically, I am losing the request function name in logs, but it could be sacrificed due to increased code readability.

          – Eugene Tiutiunnyk
          Nov 25 '18 at 1:11





          I used "saga-monitor" to see if there is any difference in the debug trace information we get from using or not using call. In fact, there is almost no difference. This is the trace line with using call: effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: request} and this is without effectTriggered {effectId: 11, parentEffectId: 10, label: "", effect: {...}} Basically, I am losing the request function name in logs, but it could be sacrificed due to increased code readability.

          – Eugene Tiutiunnyk
          Nov 25 '18 at 1:11













          Thanks for your feedback. You're correct that the put is used for dispatch actions to store. Other effects are sent to the saga middleware. I took a look using the saga-monitor-example and yes, the function name is unknown in the log. I'll update my answer to reflect my current findings about this matter.

          – Oluwafemi Sule
          Nov 25 '18 at 12:37





          Thanks for your feedback. You're correct that the put is used for dispatch actions to store. Other effects are sent to the saga middleware. I took a look using the saga-monitor-example and yes, the function name is unknown in the log. I'll update my answer to reflect my current findings about this matter.

          – Oluwafemi Sule
          Nov 25 '18 at 12:37


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53463114%2fshould-i-always-use-redux-saga-call-effect-for-functions-that-return-promise%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'