代码之家  ›  专栏  ›  技术社区  ›  robe007 Leo Aguirre

处理承诺内部回调的改进方法

  •  1
  • robe007 Leo Aguirre  · 技术社区  · 7 年前

    callbacks 里面 promises :

    const clue = 'someValue';
    
    const myFunction = (someParam, callback) => {
        someAsyncOperation(someParam) // this function returns an array
        .then((array) => {
            if (array.includes(clue)){
                callback(null, array); // Callback with 'Success'
            }
            else{
                callback(`The array does not includes: ${clue}`); // Callback with Error
            }
        })
        .catch((err) => {
            // handle error
            callback(`Some error inside the promise chain: ${err}`) // Callback with Error
        })
    }
    

    myFunction (someParam, (error, response) => {
        if(error) {
            console.log(error);
        }
        else {
            // do something with the 'response'
        }    
    })
    

    通过阅读一些文档,我发现有一些改进的方法:

    const myFunction = (someParam, callback) => {
        someAsyncOperation(someParam) // this function returns an array
        .then((array) => {
            if (array.includes(clue)){
                callback(array);
            }
            else{
                callback(`The array does not includes: ${clue}`);
            }
        }, (e) => {
            callback(`Some error happened inside the promise chain: ${e}`);
        })
        .catch((err) => {
            // handle error
            callback(`Some error happened with callbacks: ${err}`)
        })
    }
    

    我的问题是:

    'callback' function

    2 回复  |  直到 7 年前
        1
  •  1
  •   charlietfl    7 年前

    这似乎真的是倒退了,并剥夺了承诺管理错误并将其传递给整个链条的好处

    从函数返回异步承诺,不要用回调中断它。然后在链子的末端加一个钩子

    const myFunction = (someParam) => {
      // return the promise
      return someAsyncOperation(someParam) // this function returns an array
        .then((array) => {
          return array.includes(clue) ? array : [];
        });
    }
    
    myFunction(someParam).then(res=>{
      if(res.length){
         // do something with array
      }else{
         // no results
      }
    }).catch(err=>console.log('Something went wrong in chain above this'))
    
        2
  •  1
  •   jfriend00    7 年前

    不要使用来自承诺内部的回调,这是一种反模式。一旦你已经有了承诺,就用它们吧。不要“取消误导”将它们转换为回调—这在代码结构中是向后移动的。相反,只要回报你的承诺,然后你就可以使用 .then() 处理程序来设置您希望解析的值是什么,或者抛出一个错误来设置您希望被拒绝的原因是什么:

    const clue = 'someValue';
    
    const myFunction = (someParam) => {
        return someAsyncOperation(someParam).then(array => {
            if (!array.includes(clue)){
                // reject promise
                throw new Error(`The array does not include: ${clue}`);
            }
            return array;
        });
    }
    

    然后,调用者会这样做:

    myFunction(someData).then(array => {
        // success
        console.log(array);
    }).catch(err => {
        // handle error here which could be either your custom error
        // or an error from someAsyncOperation()
        console.log(err);
    });
    

    这样做的好处是,调用者可以使用承诺的所有功能将此异步操作与任何其他操作同步,轻松地将所有错误传播到一个错误处理程序,以便使用 await 等等。。。