Улучшенный способ справиться с обратными вызовами внутри обещаний - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть следующий код, который использует 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 ]

0 голосов
/ 03 сентября 2018

Не используйте обратные вызовы изнутри обещаний, это анти-шаблон. Как только у вас уже есть обещания, просто используйте их. Не «снимайте с себя», чтобы превратить их в обратные вызовы - это движется назад в структуре кода. Вместо этого просто верните обещание, и затем вы можете использовать обработчики .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 и т. Д ...

0 голосов
/ 03 сентября 2018

Это кажется очень отсталым и лишает преимущества обещаний управлять ошибками и передавать их по цепочке

Вернуть асинхронное обещание функции и не прерывать его обратными вызовами. Затем добавьте улов в конце цепочки

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