Em alguns casos, quando obtenho um valor de retorno de um objeto de promessa, preciso iniciar dois then()
precessos diferentes, dependendo da condição do valor, como:
promise().then(function(value){
if(//true) {
// do something
} else {
// do something
}
})
Estou pensando que talvez possa escrever assim:
promise().then(function(value){
if(//true) {
// call a new function which will return a new promise object
ifTruePromise().then();
} else {
ifFalsePromise().then();
}
})
mas com isso, tenho duas perguntas:
Não tenho certeza se é uma boa ideia começar uma nova promessa e depois processar em uma promessa;
e se eu precisar que os dois processos chamem uma função no último? Isso significa que eles têm o mesmo "terminal"
Tentei devolver a nova promessa de manter a corrente original como:
promise().then(function(value){
if(//true) {
// call a new function which will return a new promise object
// and return it
return ifTruePromise();
} else {
// do something, no new promise
// hope to stop the then chain
}
}).then(// I can handle the result of ifTruePromise here now);
mas, neste caso, seja verdadeiro ou falso, o próximo then
funcionará.
Então, qual é a melhor prática para lidar com isso?
node.js
asynchronous
promise
Brick Yang
fonte
fonte
Respostas:
Contanto que suas funções retornem uma promessa, você pode usar o primeiro método que sugerir.
O violino abaixo mostra como você pode seguir diferentes caminhos de encadeamento, dependendo de qual será o primeiro valor resolvido.
function myPromiseFunction() { //Change the resolved value to take a different path return Promise.resolve(true); } function conditionalChaining(value) { if (value) { //do something return doSomething().then(doSomethingMore).then(doEvenSomethingMore); } else { //do something else return doSomeOtherThing().then(doSomethingMore).then(doEvenSomethingMore); } } function doSomething() { console.log("Inside doSomething function"); return Promise.resolve("This message comes from doSomeThing function"); } function doSomeOtherThing() { console.log("Inside doSomeOtherthing function"); return Promise.resolve("This message comes from doSomeOtherThing function"); } function doSomethingMore(message) { console.log(message); return Promise.resolve("Leaving doSomethingMore"); } function doEvenSomethingMore(message) { console.log("Inside doEvenSomethingMore function"); return Promise.resolve(); } myPromiseFunction().then(conditionalChaining).then(function () { console.log("All done!"); }). catch (function (e) { });
Você também pode fazer apenas um encadeamento condicional, atribuir a promessa de retorno a uma variável e, em seguida, continuar executando as funções que devem ser executadas de qualquer maneira.
function conditionalChaining(value){ if (value) { //do something return doSomething(); } else{ //do something else return doSomeOtherThing(); } } var promise = myPromiseFunction().then(conditionalChaining); promise.then(function(value){ //keep executing functions that should be called either way });
fonte
Eu escrevi um pacote simples para uso de promessa condicional.
Se você quiser dar uma olhada:
página npm: https://www.npmjs.com/package/promise-tree
e github: https://github.com/shizongli94/promise-tree
Em resposta a comentários perguntando como o pacote resolve o problema:
1, tem dois objetos.
2, o objeto Branch neste pacote é um local de armazenamento temporário para as funções como onFulfilled e onRejected que você deseja usar em then () ou catch (). Ele tem métodos como then () e catch () que usam os mesmos argumentos das contrapartes em Promise. Ao passar um retorno de chamada em Branch.then () ou Branch.catch (), use a mesma sintaxe de Promise.then () e Promise.catch (). Em seguida, não faça nada além de armazenar os retornos de chamada em uma matriz.
3, Condition é um objeto JSON que armazena as condições e outras informações para verificação e ramificação.
4, você especifica as condições (expressão booleana) usando o objeto de condição em retornos de chamada de promessa. Condition, então, armazena as informações que você passa. Depois que todas as informações necessárias são fornecidas pelo usuário, o objeto de condição usa um método para construir um objeto Promise completamente novo que recebe informações de cadeia de promessa e retorno de chamada previamente armazenadas no objeto Branch. Uma pequena parte complicada aqui é que você (como o implementador, não o usuário) precisa resolver / rejeitar a Promessa que você construiu manualmente antes de encadear os retornos de chamada armazenados. Isso ocorre porque, caso contrário, a nova cadeia de promessa não será iniciada.
5, Graças ao loop de evento, os objetos Branch podem ser instanciados antes ou depois de você ter um objeto Promise de radical e eles não interferirão uns com os outros. Eu uso os termos "galho" e "caule" aqui porque a estrutura se assemelha a uma árvore.
O código de exemplo pode ser encontrado nas páginas npm e github.
A propósito, esta implementação também permite que você tenha ramificações dentro de uma ramificação. E as filiais não precisam estar no mesmo lugar em que você verifica as condições.
fonte
Foi assim que fiz no meu fetch () Não tenho certeza se esse é o caminho certo, mas funciona
fetch().then(res => res.ok ? res : false).then(res => { if (res) { //res ok } else { //res not ok } });
fonte