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

Improved way to deal with callbacks inside promises

我有以下代码在 promises 中使用 callbacks:

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 内部的两种方式,或者我做错了什么,我的意思是一些 promise 反模式方式?

这似乎真的倒退了,并且剥夺了 promise 管理错误并将它们传递到链中的好处

Return 函数的异步承诺,不要用回调中断它。然后在链的末尾添加一个catch

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'))

不要在 promise 内部使用回调,这是一种反模式。一旦你已经有了承诺,就使用它们。不要 "unpromisify" 将它们变成回调 - 这在代码结构中向后移动。相反,只需 return 承诺,然后您可以使用 .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 等等...