Retorne de uma promessa então ()

119

Eu tenho um código javascript como este:

function justTesting() {
  promise.then(function(output) {
    return output + 1;
  });
}

var test = justTesting();

Sempre tenho um valor indefinido para o teste var. Acho que é porque as promessas ainda não foram resolvidas ... há como devolver o valor de uma promessa?

Priscy
fonte
21
o valor de retorno de uma then()chamada é novamente uma promessa, que envolve o valor que você retornou.
Sirko
Você tem um erro de sintaxe, acho que nem mesmo analisa.
Djechlin
4
test é indefinido porque justTesting não retorna nada em seu exemplo (você não tem retorno). Adicione um retorno e o teste será definido como uma promessa.
Jerome WAGNER
1
Obrigado pelo feedback ... o ponto é atribuir a saída +1 para testar.
Priscy
4
Qual é a variável promise. Você não o mostra definido em nenhum lugar e não retorna nada de sua justTesting()função. Se quiser uma ajuda melhor, você precisa descrever o problema que está tentando resolver, em vez de apenas nos mostrar um código tão "errado" que nem mesmo ilustra o que você está realmente tentando fazer. Explique o problema que você está tentando resolver.
jfriend00

Respostas:

136

Quando você retorna algo de um then()retorno de chamada, é um pouco mágico. Se você retornar um valor, o próximo then()será chamado com esse valor. No entanto, se você retornar algo semelhante a uma promessa, o próximo then()espera por isso e só é chamado quando a promessa é estabelecida (sucesso / falha).

Fonte: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queuing-asynchronous-actions

c0ming
fonte
parece que por esse motivo, então posso prometer cadeia para iterar array com solicitações Ajax de forma síncrona em stackoverflow.com/q/53651266/2028440
Bằng Rikimaru
84
Não respondeu à pergunta.
Andrew
Link
Marinos An
1
Qual é a solução?
Apurva
58

Para usar uma promessa, você deve chamar uma função que cria uma promessa ou você mesmo deve criar uma. Você realmente não descreve o problema que está tentando resolver, mas veja como você mesmo criaria uma promessa:

function justTesting(input) {
    return new Promise(function(resolve, reject) {
        // some async operation here
        setTimeout(function() {
            // resolve the promise with some value
            resolve(input + 10);
        }, 500);
    });
}

justTesting(29).then(function(val) {
   // you access the value from the promise here
   log(val);
});

// display output in snippet
function log(x) {
    document.write(x);
}

Ou, se você já tem uma função que retorna uma promessa, pode usar essa função e retornar sua promessa:

// function that returns a promise
function delay(t) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, t);
  });
}

function justTesting(input) {
  return delay(100).then(function() {
    return input + 10;
  });
}

justTesting(29).then(function(val) {
  // you access the value from the promise here
  log(val);
});

// display output in snippet
function log(x) {
  document.write(x);
}

jfriend00
fonte
2
o que me confunde é o dobro return, ou seja, justTestingdiz return.then => return. Eu sei que isso funciona bcs Eu implementei isso (bcs linting me forçou a, longe new Promise), mas você pode explicar como entender / pensar nesse par retorno / retorno?
Ronnie Royston
2
@RonRoyston - Em primeiro lugar, a função que você passa .then()é uma função separada da função que o contém, portanto, quando é chamada, tem seu próprio valor de retorno. Em segundo lugar, o valor de retorno de um .then()manipulador se torna o valor resolvido da promessa. Portanto, .then(val => {return 2*val;})está alterando o valor resolvido de valpara 2*val.
jfriend00
13

O que fiz aqui é retornar uma promessa da função justTesting. Você pode obter o resultado quando a função for resolvida.

// new answer

function justTesting() {
  return new Promise((resolve, reject) => {
    if (true) {
      return resolve("testing");
    } else {
      return reject("promise failed");
   }
 });
}

justTesting()
  .then(res => {
     let test = res;
     // do something with the output :)
  })
  .catch(err => {
    console.log(err);
  });

Espero que isto ajude!

// old answer

function justTesting() {
  return promise.then(function(output) {
    return output + 1;
  });
}

justTesting().then((res) => {
     var test = res;
    // do something with the output :)
    }
Vidur Singla
fonte
O que aconteceria se em "// fazer algo com a saída" eu colocasse uma instrução de retorno? Por exemplo: eu teria "JustTesting (). Then ..." dentro de uma função pai. Eu seria capaz de retornar um valor na parte "then"?
mrzepka
Se você deseja retornar um valor de // fazer algo com a saída, você terá que adicionar um retorno antes de justTesing (). Exemplo, "return justTesting (). Then ((res) => {return res;});
Vidur Singla
Tudo bem, era o que eu esperava, só queria ter certeza :) Obrigado!
Mrzepka
e se retornarmos o teste a partir de então?
MeVimalkumar
3

Eu prefiro usar o comando "await" e funções assíncronas para me livrar de confusões de promessas,

Neste caso, eu escreveria uma função assíncrona primeiro; ela será usada em vez da função anônima chamada em "promessa. Então" parte desta pergunta:

async function SubFunction(output){

   // Call to database , returns a promise, like an Ajax call etc :

   const response = await axios.get( GetApiHost() + '/api/some_endpoint')

   // Return :
   return response;

}

e então eu chamaria esta função da função principal:

async function justTesting() {
   const lv_result = await SubFunction(output);

   return lv_result + 1;
}

Observando que retornei a função principal e a subfunção para funções assíncronas aqui.

apicultor
fonte
Certo ... O uso de await o tornou muito mais limpo e também resolveu o problema
karthikeyan