美文网首页
[译] resolve或reject之后还需要return吗?

[译] resolve或reject之后还需要return吗?

作者: d6e83ee69161 | 来源:发表于2018-04-17 14:32 被阅读1983次

    原文:Do I need to return after early resolve/reject?

    问:

    假设我有如下的代码

    function divide(numerator, denominator) {
     return new Promise((resolve, reject) => {
    
      if(denominator === 0){
       reject("Cannot divide by 0");
       return; //superfluous?
      }
    
      resolve(numerator / denominator);
    
     });
    }
    

    如果我的目的是利用reject提前退出,我是否应该在它之后也立刻加一个return呢?

    答:

    return的作用就在于rejection后终止函数的执行,并且阻止后面代码的执行。

    function divide(numerator, denominator) {
      return new Promise((resolve, reject) => {
    
        if (denominator === 0) {
          reject("Cannot divide by 0");
          return; //函数执行到此结束
        }
    
        resolve(numerator / denominator);
      });
    }
    

    在这个例子中它阻止了resolve(numerator / denominator);的执行,严格意义上这里是不需要return的。但是,仍然建议加上它来立刻阻止执行来避免一些潜在的麻烦。另外,避免执行不必要的代码是一个良好的实践。

    背景

    一个promise可以处于3种状态中的一种:

    1. pending - 初始状态。从pending状态我们可以切换到另外的状态
    2. fulfilled - 成功的操作
    3. rejected - 失败的操作

    当一个promise是fulfilled或者rejected状态时,它将会一直维持该状态。所以,reject一个fulfilled的promise或者fulfill一个rejected的promise是没有任何效果的。

    下面的代码片段展示了即使一个promise在rejected后被fulfill,那也是没什么卵用的。

    function divide(numerator, denominator) {
      return new Promise((resolve, reject) => {
        if (denominator === 0) {
          reject("Cannot divide by 0");
        }
    
        resolve(numerator / denominator);
      });
    }
    
    divide(5,0)
      .then((result) => console.log('result: ', result))
      .catch((error) => console.log('error: ', error));
    
    
    // 输出结果
    error:  Cannot divide by 0
    

    所以我们为什么需要return?

    尽管我们无法改变一个已经改变过状态的promise,但是reject和resolve都无法让函数剩下的部分暂停执行。那函数中包含的其他代码可能会对我们造成干扰。举例:

    function divide(numerator, denominator) {
      return new Promise((resolve, reject) => {
        if (denominator === 0) {
          reject("Cannot divide by 0");
        }
        
        console.log('operation succeeded');
    
        resolve(numerator / denominator);
      });
    }
    
    divide(5, 0)
      .then((result) => console.log('result: ', result))
      .catch((error) => console.log('error: ', error));
    
    // 输出结果
    operation succeeded
    error:  Cannot divide by 0
    

    即使函数现在不包含这种代码,也保不齐将来会有。将来的重构者可能会弄不明白,也很难debug。

    在resolve/reject后停止执行

    这是标准JS控制流程:

    • resolve / reject 后return:
    function divide(numerator, denominator) {
      return new Promise((resolve, reject) => {
        if (denominator === 0) {
          reject("Cannot divide by 0");
          return;
        }
    
        console.log('operation succeeded');
    
        resolve(numerator / denominator);
      });
    }
    
    divide(5, 0)
      .then((result) => console.log('result: ', result))
      .catch((error) => console.log('error: ', error));
    
    • return时带上 resolve / reject - 因为回调函数的return值是被忽略的,所以我们这里能少写一行代码:
    function divide(numerator, denominator) {
      return new Promise((resolve, reject) => {
        if (denominator === 0) {
          return reject("Cannot divide by 0");
        }
    
        console.log('operation succeeded');
    
        resolve(numerator / denominator);
      });
    }
    
    divide(5, 0)
      .then((result) => console.log('result: ', result))
      .catch((error) => console.log('error: ', error));
    
    • 使用 if/else 代码块:
    function divide(numerator, denominator) {
      return new Promise((resolve, reject) => {
        if (denominator === 0) {
          reject("Cannot divide by 0");
        } else {
          console.log('operation succeeded');
          resolve(numerator / denominator);
        }
      });
    }
    
    divide(5, 0)
      .then((result) => console.log('result: ', result))
      .catch((error) => console.log('error: ', error));
    

    我个人是倾向于使用return的方式的,这样代码看起来比较漂亮。

    相关文章

      网友评论

          本文标题:[译] resolve或reject之后还需要return吗?

          本文链接:https://www.haomeiwen.com/subject/vnwukftx.html