Trở lại sau một lời hứa ()


118

Tôi có một mã javascript như thế này:

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

var test = justTesting();

Tôi luôn có một giá trị không xác định cho bài kiểm tra var. Tôi nghĩ rằng đó là bởi vì những lời hứa vẫn chưa được giải quyết..có cách nào để trả lại giá trị từ một lời hứa?


21
giá trị trả về của một then()cuộc gọi lại là một lời hứa, bao bọc giá trị mà bạn trả về.
Sirko

Bạn có một lỗi cú pháp, tôi không nghĩ rằng điều này thậm chí còn phân tích cú pháp.
djechlin

4
kiểm tra không được xác định vì justTesting không trả lại gì trong ví dụ của bạn (bạn không có trả về). Thêm một trả lại và kiểm tra sẽ được định nghĩa như một lời hứa.
Jerome WAGNER

1
Cảm ơn bạn đã phản hồi .. điểm là chỉ định đầu ra +1 để kiểm tra.
Priscy

4
Biến là gì promise. Bạn không hiển thị nó được xác định ở bất kỳ đâu và bạn không trả về bất kỳ thứ gì từ justTesting()hàm của mình . Nếu bạn muốn được trợ giúp tốt hơn, bạn cần mô tả vấn đề bạn đang cố gắng giải quyết thay vì chỉ hiển thị cho chúng tôi mã quá "tắt" đến mức nó thậm chí không minh họa những gì bạn thực sự đang cố gắng làm. Giải thích vấn đề bạn đang cố gắng giải quyết.
jfriend00

Câu trả lời:


136

Khi bạn trả lại một thứ gì đó từ một then()cuộc gọi lại, đó là một điều kỳ diệu. Nếu bạn trả về một giá trị, giá trị tiếp theo then()được gọi với giá trị đó. Tuy nhiên, nếu bạn trả về một thứ gì đó giống như lời hứa, thì phần tiếp theo sẽ then()đợi nó và chỉ được gọi khi lời hứa đó lắng xuống (thành công / thất bại).

Nguồn: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queue-asynchronous-actions


Có vẻ như vì lý do này, sau đó tôi có thể thực hiện chuỗi hứa hẹn để lặp lại mảng với các yêu cầu Ajax một cách đồng bộ trong stackoverflow.com/q/53651266/2028440
Bằng Rikimaru

82
Không trả lời câu hỏi.
Andrew


1
Vậy giải pháp là gì?
Apurva

58

Để sử dụng một lời hứa, bạn phải gọi một hàm tạo lời hứa hoặc bạn phải tự tạo một lời hứa. Bạn không thực sự mô tả vấn đề bạn thực sự đang cố gắng giải quyết, nhưng đây là cách bạn sẽ tự tạo ra một lời hứa:

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

Hoặc, nếu bạn đã có một hàm trả về một lời hứa, bạn có thể sử dụng hàm đó và trả về lời hứa của nó:

// 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
những gì ném tôi đi là gấp đôi return, tức là justTestingnói return.then => return. Tôi biết điều này hoạt động bcs Tôi đã triển khai điều này (bcs linting buộc tôi phải tránh xa new Promise), nhưng bạn có thể giải thích cách hiểu / nghĩ về cặp trả về / trả về đó không?
Ronnie Royston

2
@RonRoyston - Trước hết, hàm bạn chuyển đến .then()là một hàm riêng biệt với hàm chứa nên khi nó được gọi, nó có giá trị trả về riêng. Thứ hai, giá trị trả về từ một .then()trình xử lý trở thành giá trị được giải quyết của lời hứa. Vì vậy, .then(val => {return 2*val;})đang thay đổi giá trị được phân giải từ valthành 2*val.
jfriend00 14/09/18

13

Những gì tôi đã làm ở đây là tôi đã trả về một lời hứa từ hàm justTesting. Sau đó, bạn có thể nhận được kết quả khi chức năng được giải quyết.

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

Hi vọng điêu nay co ich!

// old answer

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

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

Điều gì sẽ xảy ra nếu trong "// làm gì đó với đầu ra" tôi đặt câu lệnh trả về? Ví dụ: Tôi sẽ có "JustTesting (). Then ..." trong một hàm cha. Tôi có thể trả về một giá trị trong phần "then" không?
mrzepka

Nếu bạn muốn trả về một giá trị từ // làm gì đó với đầu ra, bạn sẽ phải thêm một giá trị trả về trước justTesing (). Ví dụ, "return justTesting (). Then ((res) => {return res;});
Vidur Singla 23/09/17

Được rồi, đó là những gì tôi mong đợi, tôi chỉ muốn đảm bảo :) Cảm ơn!
mrzepka

điều gì sẽ xảy ra nếu chúng tôi trả lại bài kiểm tra từ đó?
MeVimalkumar

3

Tôi thích sử dụng lệnh "await" và các hàm không đồng bộ để loại bỏ sự nhầm lẫn về lời hứa,

Trong trường hợp này, trước tiên tôi sẽ viết một hàm không đồng bộ, hàm này sẽ được sử dụng thay vì hàm ẩn danh được gọi trong phần "promise.then" của câu hỏi này:

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;

}

và sau đó tôi sẽ gọi hàm này từ hàm main:

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

   return lv_result + 1;
}

Lưu ý rằng tôi đã trả lại cả hàm chính và hàm phụ cho các hàm không đồng bộ ở đây.


Ngay ... Sử dụng chờ đợi làm cho nó nhiều bụi cũng như giải quyết vấn đề này
Karthikeyan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.