Вернитесь из обещания then ()


119

У меня есть такой код javascript:

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

var test = justTesting();

У меня всегда есть неопределенное значение для теста var. Я думаю, это потому, что обещания еще не решены ... есть способ вернуть значение из обещания?


21
возвращаемое значение then()вызова снова является обещанием, которое обертывает возвращенное вами значение.
Sirko

У вас синтаксическая ошибка, я не думаю, что это даже разбирает.
djechlin

4
test не определен, потому что justTesting ничего не возвращает в вашем примере (у вас нет возврата). Добавьте возврат, и тест будет определен как обещание.
Джером ВАГНЕР

1
Спасибо за отзыв .. дело в том, чтобы назначить выход +1 для тестирования.
Priscy

4
Что такое переменная promise. Вы нигде не показываете, что он определен, и ничего не возвращаете из своей justTesting()функции. Если вам нужна более качественная помощь, вам нужно описать, какую проблему вы пытаетесь решить, а не просто показывать нам код, который настолько «не работает», что даже не иллюстрирует, что вы действительно пытаетесь сделать. Объясните проблему, которую вы пытаетесь решить.
jfriend00 05

Ответы:


135

Когда вы возвращаете что-то из then()обратного вызова, это немного волшебно. Если вы возвращаете значение, следующий then()вызывается с этим значением. Однако, если вы возвращаете что-то похожее на обещание, следующее then()ожидает этого и вызывается только тогда, когда это обещание устанавливается (выполняется / не выполняется).

Источник: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queuing-asynchronous-actions.


кажется, по этой причине я могу сделать цепочку обещаний для итерации массива с запросами Ajax синхронно в stackoverflow.com/q/53651266/2028440
Bằng Rikimaru

87
Не ответил на вопрос.
Эндрю

Связанная ссылка
Marinos An

1
Итак, какое решение?
Апурва,

58

Чтобы использовать обещание, вы должны либо вызвать функцию, которая создает обещание, либо создать его самостоятельно. На самом деле вы не описываете, какую проблему на самом деле пытаетесь решить, но вот как вы могли бы создать обещание самостоятельно:

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);
}

Или, если у вас уже есть функция, которая возвращает обещание, вы можете использовать эту функцию и вернуть ее обещание:

// 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);
}


2
то , что бросает меня является двойным return, то есть justTestingговорит return.then => return. Я знаю, что это работает. Bcs. Я реализовал это (bcs linting заставил меня отказаться от этого new Promise), но не могли бы вы объяснить, как понять / подумать об этой паре возврата / возврата?
Ронни Ройстон

2
@RonRoyston - Во-первых, функция, которую вы передаете, .then()является отдельной функцией от содержащейся функции, поэтому при ее вызове она имеет собственное возвращаемое значение. Во-вторых, возвращаемое значение .then()обработчика становится разрешенным значением обещания. Итак, .then(val => {return 2*val;})изменяется разрешенное значение с valна 2*val.
jfriend00

13

Что я здесь сделал, так это то, что я вернул обещание от функции justTesting. Затем вы можете получить результат, когда функция будет разрешена.

// 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);
  });

Надеюсь это поможет!

// old answer

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

justTesting().then((res) => {
     var test = res;
    // do something with the output :)
    }

Что произойдет, если в строке «// сделать что-нибудь с выводом» я поставлю оператор возврата? Например: у меня будет «JustTesting (). Then ...» в родительской функции. Смогу ли я вернуть значение в части «тогда»?
mrzepka

Если вы хотите вернуть значение из // сделать что-нибудь с выводом, вам нужно будет добавить возврат перед justTesing (). Пример: «return justTesting (). Then ((res) => {return res;});
Видур Сингла,

Хорошо, это то, что я ожидал, просто хотел убедиться :) Спасибо!
mrzepka

что, если мы вернем тест оттуда?
MeVimalkumar

4

Я предпочитаю использовать команду "await" и асинхронные функции, чтобы избавиться от путаницы с обещаниями,

В этом случае я бы сначала написал асинхронную функцию, она будет использоваться вместо анонимной функции, вызываемой в части этого вопроса "prom.then":

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;

}

а затем я бы вызвал эту функцию из основной функции:

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

   return lv_result + 1;
}

Отметив, что здесь я вернул в асинхронные функции как основную, так и вспомогательную функцию.


Хорошо ... Использование await сделало его намного чище, а также решило проблему
Картикеян
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.