กลับจากคำสัญญาแล้ว ()


119

ฉันมีรหัสจาวาสคริปต์เช่นนี้:

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

var test = justTesting();

ฉันมีค่าที่ไม่ได้กำหนดไว้เสมอสำหรับการทดสอบ var ฉันคิดว่าคงเป็นเพราะคำสัญญาที่ยังไม่ได้รับการแก้ไข .. มีวิธีคืนค่าจากคำสัญญาหรือไม่?


21
มูลค่าผลตอบแทนของการthen()โทรเป็นคำสัญญาอีกครั้งซึ่งครอบคลุมมูลค่าที่คุณส่งคืน
Sirko

คุณมีข้อผิดพลาดทางไวยากรณ์ฉันไม่คิดว่าสิ่งนี้จะแยกวิเคราะห์
djechlin

4
การทดสอบไม่ได้กำหนดไว้เนื่องจาก justTesting ไม่ส่งคืนค่าใดในตัวอย่างของคุณ (คุณไม่มีผลตอบแทน) เพิ่มผลตอบแทนและการทดสอบจะกำหนดเป็นสัญญา
Jerome WAGNER

1
ขอบคุณสำหรับข้อเสนอแนะ .. ประเด็นคือกำหนดเอาต์พุต +1 เพื่อทดสอบ
Priscy

4
ตัวแปรคืออะไรpromise. คุณไม่แสดงที่กำหนดไว้ที่ใดก็ได้และคุณจะไม่ส่งคืนอะไรจากjustTesting()ฟังก์ชันของคุณ หากคุณต้องการความช่วยเหลือที่ดีขึ้นคุณต้องอธิบายถึงปัญหาที่คุณกำลังพยายามแก้ไขแทนที่จะแสดงโค้ดที่ "ปิด" ให้เราเห็นโดยที่มันไม่ได้แสดงถึงสิ่งที่คุณกำลังพยายามทำจริงๆ อธิบายปัญหาที่คุณกำลังพยายามแก้ไข
jfriend00

คำตอบ:


135

เมื่อคุณส่งคืนบางสิ่งจากการthen()โทรกลับมันวิเศษมาก หากคุณส่งคืนค่าค่าถัดไปthen()จะถูกเรียกด้วยค่านั้น อย่างไรก็ตามหากคุณส่งคืนสิ่งที่เหมือนคำสัญญาสิ่งต่อไปthen()จะรอและจะถูกเรียกก็ต่อเมื่อสัญญานั้นตกลง (สำเร็จ / ล้มเหลว)

ที่มา: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queuing-asynchronous-actions


ดูเหมือนจะเป็นเพราะเหตุนี้ฉันจึงสามารถทำสัญญา chain สำหรับการวนซ้ำอาร์เรย์ด้วยคำขอ Ajax พร้อมกันในstackoverflow.com/q/53651266/2028440
Bằng Rikimaru

88
ไม่ได้ตอบคำถาม.
Andrew


1
แล้วทางออกคืออะไร?
Apurva

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) แต่คุณสามารถอธิบายวิธีทำความเข้าใจ / คิดของคู่รีเทิร์น / รีเทิร์นนั้นได้อย่างไร
Ronnie Royston

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

จะเกิดอะไรขึ้นถ้าใน "// ทำบางอย่างกับผลลัพธ์" ฉันใส่คำสั่ง return? ตัวอย่างเช่นฉันจะมี "JustTesting () แล้ว ... " ภายในฟังก์ชันหลัก ฉันจะคืนค่าภายในส่วน "แล้ว" ได้หรือไม่
mrzepka

หากคุณต้องการคืนค่าจาก // ทำบางสิ่งกับผลลัพธ์คุณจะต้องเพิ่มผลตอบแทนก่อน justTesing () ตัวอย่าง "return justTesting (). then ((res) => {return res;});
Vidur Singla

นั่นคือสิ่งที่ฉันคาดไว้ฉันแค่อยากให้แน่ใจ :) ขอบคุณ!
mrzepka

จะเกิดอะไรขึ้นถ้าเรากลับมาทดสอบจากนั้น?
MeVimalkumar

4

ฉันชอบใช้คำสั่ง "รอ" และฟังก์ชัน async เพื่อกำจัดความสับสนของคำสัญญา

ในกรณีนี้ฉันจะเขียนฟังก์ชันอะซิงโครนัสก่อนสิ่งนี้จะถูกใช้แทนฟังก์ชันที่ไม่ระบุตัวตนที่เรียกว่าภายใต้ "สัญญาแล้ว" ส่วนหนึ่งของคำถามนี้:

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

สังเกตว่าฉันส่งคืนทั้งฟังก์ชันหลักและฟังก์ชันย่อยเป็นฟังก์ชัน async ที่นี่


ถูกต้อง ... การใช้การรอคอยทำให้มันสะอาดขึ้นมากและแก้ไขปัญหาได้
karthikeyan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.