ฉันเห็นโค้ดที่มีลักษณะ:
myObj.doSome("task").then(function(env) {
// logic
});
ในกรณีที่ไม่then()มาจากไหน?
ฉันเห็นโค้ดที่มีลักษณะ:
myObj.doSome("task").then(function(env) {
// logic
});
ในกรณีที่ไม่then()มาจากไหน?
คำตอบ:
วิธีดั้งเดิมในการจัดการกับการโทรแบบอะซิงโครนัสใน JavaScript นั้นเป็นการโทรกลับ สมมติว่าเราต้องทำการติดต่อสามครั้งไปยังเซิร์ฟเวอร์เพื่อตั้งค่าแอปพลิเคชันของเรา ด้วยการเรียกกลับรหัสอาจมีลักษณะดังต่อไปนี้ (สมมติว่าฟังก์ชั่น xhrGET เพื่อโทรเซิร์ฟเวอร์):
// Fetch some server configuration
xhrGET('/api/server-config', function(config) {
// Fetch the user information, if he's logged in
xhrGET('/api/' + config.USER_END_POINT, function(user) {
// Fetch the items for the user
xhrGET('/api/' + user.id + '/items', function(items) {
// Actually display the items here
});
});
});
ในตัวอย่างนี้เราเรียกข้อมูลการกำหนดค่าเซิร์ฟเวอร์ก่อน จากนั้นเราจะดึงข้อมูลเกี่ยวกับผู้ใช้ปัจจุบันและในที่สุดก็จะได้รับรายการของผู้ใช้ปัจจุบัน การเรียก xhrGET แต่ละครั้งจะใช้ฟังก์ชันการเรียกกลับที่ดำเนินการเมื่อเซิร์ฟเวอร์ตอบสนอง
ตอนนี้แน่นอนว่าเรามีการทำรังในระดับที่มากขึ้นรหัสที่ยากขึ้นคือการอ่านแก้จุดบกพร่องบำรุงรักษาอัปเกรดและใช้งานได้โดยทั่วไป สิ่งนี้เรียกกันโดยทั่วไปว่านรกการเรียกกลับ นอกจากนี้หากเราต้องการจัดการข้อผิดพลาดเราอาจต้องผ่านฟังก์ชั่นอื่นไปยังการเรียก xhrGET แต่ละครั้งเพื่อบอกสิ่งที่จำเป็นต้องทำในกรณีที่เกิดข้อผิดพลาด หากเราต้องการมีตัวจัดการข้อผิดพลาดทั่วไปเพียงตัวเดียวนั่นเป็นไปไม่ได้
Promise API ออกแบบมาเพื่อแก้ปัญหาการซ้อนและปัญหาการจัดการข้อผิดพลาด
Promise API เสนอสิ่งต่อไปนี้:
promiseวัตถุpromiseวัตถุจะมีthenฟังก์ชั่นที่สามารถรับอาร์กิวเมนต์สองsuccess
ตัวคือตัวจัดการและerrorตัวจัดการthenฟังก์ชันจะถูกเรียกเพียงครั้งเดียวหลังจากงานอะซิงโครนัสเสร็จสิ้นthenฟังก์ชั่นยังจะกลับมาpromiseเพื่อให้การผูกมัดหลายสายvalueซึ่งจะถูกส่งผ่านไปยังฟังก์ชันถัดไปargumentในรูปแบบห่วงโซ่ของpromisespromise(สร้างคำร้องขอแบบอะซิงโครนัสอีกครั้ง) ตัวจัดการถัดไป (ความสำเร็จหรือข้อผิดพลาด) จะถูกเรียกหลังจากการร้องขอนั้นเสร็จสิ้นดังนั้นโค้ดตัวอย่างก่อนหน้านี้อาจแปลเป็นดังนี้: ใช้สัญญาและ$httpบริการ (ใน AngularJs):
$http.get('/api/server-config').then(
function(configResponse) {
return $http.get('/api/' + configResponse.data.USER_END_POINT);
}
).then(
function(userResponse) {
return $http.get('/api/' + userResponse.data.id + '/items');
}
).then(
function(itemResponse) {
// Display items here
},
function(error) {
// Common error handling
}
);
การเผยแพร่ความสำเร็จและข้อผิดพลาด
การผูกมัดสัญญาเป็นเทคนิคที่ทรงพลังมากที่ช่วยให้เราสามารถใช้งานได้หลายอย่างเช่นการให้บริการโทรออกเซิร์ฟเวอร์ทำการประมวลผลข้อมูลบางส่วนแล้วประมวลผลข้อมูลกลับไปยังคอนโทรลเลอร์ แต่เมื่อเราทำงานด้วย
promiseโซ่มีบางสิ่งที่เราต้องจำไว้
พิจารณาpromiseห่วงโซ่สมมุติต่อไปนี้ด้วยสามสัญญา P1, P2 และ P3 แต่ละตัวpromiseมีตัวจัดการสำเร็จและตัวจัดการข้อผิดพลาดดังนั้น S1 และ E1 สำหรับ P1, S2 และ E2 สำหรับ P2, S3 และ E3 และ E3 สำหรับ P3:
xhrCall()
.then(S1, E1) //P1
.then(S2, E2) //P2
.then(S3, E3) //P3
ในการไหลปกติของสิ่งต่าง ๆ ที่ไม่มีข้อผิดพลาดแอปพลิเคชันจะไหลผ่าน S1, S2 และสุดท้าย S3 แต่ในชีวิตจริงสิ่งต่าง ๆ ไม่เคยราบรื่นเช่นนั้น P1 อาจพบข้อผิดพลาดหรือ P2 อาจพบข้อผิดพลาดทำให้เกิด E1 หรือ E2
พิจารณากรณีต่อไปนี้:
•เราได้รับการตอบสนองที่ประสบความสำเร็จจากเซิร์ฟเวอร์ใน P1 แต่ข้อมูลที่ส่งคืนนั้นไม่ถูกต้องหรือไม่มีข้อมูลในเซิร์ฟเวอร์ (คิดว่าอาร์เรย์ว่างเปล่า) ในกรณีเช่นนี้สำหรับ P2 สัญญาถัดไปก็ควรทริกเกอร์ตัวจัดการข้อผิดพลาด E2
•เราได้รับข้อผิดพลาดสำหรับสัญญา P2 ทำให้เกิด E2 แต่ภายในตัวจัดการเรามีข้อมูลจากแคชเพื่อให้แน่ใจว่าแอปพลิเคชันสามารถโหลดได้ตามปกติ ในกรณีนั้นเราอาจต้องการให้แน่ใจว่าหลังจากเรียก E2, S3
ดังนั้นทุกครั้งที่เราเขียนความสำเร็จหรือตัวจัดการข้อผิดพลาดเราจำเป็นต้องโทรออก - เนื่องจากฟังก์ชั่นปัจจุบันของเรานี่คือสัญญาที่ว่าจะประสบความสำเร็จหรือล้มเหลวสำหรับผู้จัดการต่อไปในห่วงโซ่สัญญา
หากเราต้องการเรียกตัวจัดการความสำเร็จสำหรับสัญญาครั้งต่อไปในโซ่เราก็สามารถคืนค่าจากความสำเร็จหรือตัวจัดการข้อผิดพลาด
ในทางกลับกันหากเราต้องการทริกเกอร์ตัวจัดการข้อผิดพลาดสำหรับคำสัญญาต่อไปในโซ่เราสามารถทำได้โดยใช้deferredวัตถุและเรียกreject()วิธีการของมัน
ตอนนี้วัตถุรอการตัดบัญชีคืออะไร?
วัตถุที่เลื่อนออกไปใน jQuery หมายถึงหน่วยของงานที่จะแล้วเสร็จในภายหลังโดยทั่วไปจะไม่ตรงกัน เมื่อหน่วยของงานเสร็จสมบูรณ์
deferredวัตถุสามารถตั้งค่าให้แก้ไขหรือล้มเหลว
deferredวัตถุมีpromiseวัตถุ ผ่านpromiseวัตถุที่คุณสามารถระบุสิ่งที่จะเกิดขึ้นเมื่อหน่วยงานเสร็จสมบูรณ์ คุณทำได้โดยการตั้งค่าฟังก์ชั่นการโทรกลับบนpromiseวัตถุ
วัตถุที่ถูกเลื่อนเวลาใน Jquery: https://api.jquery.com/jquery.deferred/
วัตถุที่ถูกเลื่อนเวลาใน AngularJs: https://docs.angularjs.org/api/ng/service/ $ q
() ฟังก์ชั่นนั้นเกี่ยวข้องกับ "สัญญาจาวาสคริปต์" ที่ใช้ในห้องสมุดหรือกรอบบางอย่างเช่น jQuery หรือ AngularJS
คำมั่นสัญญาเป็นรูปแบบสำหรับการจัดการการดำเนินงานแบบอะซิงโครนัส คำสัญญาอนุญาตให้คุณเรียกวิธีการที่เรียกว่า "จากนั้น" ซึ่งช่วยให้คุณระบุฟังก์ชันที่จะใช้เป็นการเรียกกลับ
ดูข้อมูลเพิ่มเติมได้ที่: http://wildermuth.com/2013/8/3/JavaScript_Promises
และสำหรับสัญญาเชิงมุม: http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/
A promise can only succeed or fail onceและIf a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called
สำหรับความรู้ของฉันไม่มีthen()วิธีการในตัวjavascript(ในขณะที่เขียนนี้)
ปรากฏว่าสิ่งที่มันคือการที่จะกลับมามีวิธีการที่เรียกว่าdoSome("task")then
หากคุณบันทึกผลลัพธ์การส่งคืนของdoSome()คอนโซลคุณควรเห็นคุณสมบัติของสิ่งที่ถูกส่งคืน
console.log( myObj.doSome("task") ); // Expand the returned object in the
// console to see its properties.
ปรับปรุง (ณ ECMAScript6) : -
.then()ฟังก์ชั่นได้รับการรวมเพื่อจาวาสคริปต์บริสุทธิ์
จากเอกสาร Mozilla นี่ ,
เมธอด then () จะส่งคืนสัญญา มันต้องใช้สองข้อโต้แย้ง: ฟังก์ชั่นการโทรกลับสำหรับกรณีที่ประสบความสำเร็จและความล้มเหลวของสัญญา
ในทางกลับกันวัตถุสัญญานั้นถูกกำหนดให้เป็น
วัตถุสัญญาจะใช้สำหรับการคำนวณที่เลื่อนออกไปและแบบอะซิงโครนัส สัญญาหมายถึงการดำเนินการที่ยังไม่เสร็จ แต่คาดว่าจะเกิดขึ้นในอนาคต
นั่นคือการPromiseกระทำเป็นตัวยึดตำแหน่งสำหรับค่าที่ยังไม่ได้คำนวณ แต่จะได้รับการแก้ไขในอนาคต และ.then()ฟังก์ชั่นนี้ใช้เพื่อเชื่อมโยงฟังก์ชั่นที่จะเรียกใช้บน Promise เมื่อแก้ไขแล้ว - ไม่ว่าจะเป็นความสำเร็จหรือความล้มเหลว
.thenแต่คำสัญญาดั้งเดิมกำลังมาใน ES6: html5rocks.com/en/tutorials/es6/promises
นี่คือสิ่งที่ฉันทำเพื่อตัวเองเพื่อเคลียร์ว่าสิ่งต่าง ๆ ทำงานอย่างไร ฉันเดาว่าคนอื่น ๆ ก็สามารถพบตัวอย่างที่เป็นประโยชน์นี้ได้:
doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');
// For pedagogical reasons I originally wrote the following doit()-function so that
// it was clear that it is a promise. That way wasn't really a normal way to do
// it though, and therefore Slikts edited my answer. I therefore now want to remind
// you here that the return value of the following function is a promise, because
// it is an async function (every async function returns a promise).
async function doit() {
log('Calling someTimeConsumingThing');
await someTimeConsumingThing();
log('Ready with someTimeConsumingThing');
}
function someTimeConsumingThing() {
return new Promise(function(resolve,reject) {
setTimeout(resolve, 2000);
})
}
function log(txt) {
document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>
แล้วเป็นวิธีการโทรกลับสแต็คซึ่งสามารถใช้ได้หลังจากสัญญาได้รับการแก้ไขมันเป็นส่วนหนึ่งของห้องสมุดเช่น jQuery แต่ตอนนี้มันมีอยู่ใน JavaScript พื้นเมืองและด้านล่างเป็นคำอธิบายรายละเอียดวิธีการทำงาน
คุณสามารถทำสัญญาในภาษาจาวาสคริปต์ได้เช่นเดียวกับที่มีสัญญาใน jQuery ทุกสัญญาสามารถซ้อนกันและสามารถเรียกได้ด้วย Resolve และ Reject callbacks นี่คือวิธีที่คุณสามารถเชื่อมโยงการโทรแบบอะซิงโครนัส
ฉันแยกและแก้ไขจากเอกสาร MSDN เกี่ยวกับสถานะการชาร์จแบตเตอรี่ ..
สิ่งนี้จะลองดูว่าผู้ใช้แล็ปท็อปหรืออุปกรณ์ชาร์จแบตเตอรี่หรือไม่ จากนั้นจะถูกเรียกใช้และคุณสามารถทำงานให้สำเร็จได้
navigator
.getBattery()
.then(function(battery) {
var charging = battery.charging;
alert(charging);
})
.then(function(){alert("YeoMan : SINGH is King !!");});
function fetchAsync (url, timeout, onData, onError) {
…
}
let fetchPromised = (url, timeout) => {
return new Promise((resolve, reject) => {
fetchAsync(url, timeout, resolve, reject)
})
}
Promise.all([
fetchPromised("http://backend/foo.txt", 500),
fetchPromised("http://backend/bar.txt", 500),
fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
let [ foo, bar, baz ] = data
console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
console.log(`error: ${err}`)
})
ความหมาย :: แล้วเป็นวิธีการที่ใช้ในการแก้ปัญหาการเรียกกลับ Asynchronous
สิ่งนี้ถูกนำมาใช้ในES6
โปรดหาเอกสารที่เหมาะสมที่นี่สัญญา Es6
thenมาจากที่ใดและทำงานอย่างไร คุณควรปรับปรุงคำตอบเพื่อให้รายละเอียดเหล่านั้น
ฉันสงสัยว่า doSome คืนค่านี้ซึ่งก็คือ myObj ซึ่งก็มีวิธีการเช่นกัน ผูกมัดวิธีมาตรฐาน ...
ถ้า doSome ไม่ได้คืนสิ่งนี้เป็นวัตถุที่ doSome ถูกดำเนินการโปรดมั่นใจว่ากำลังคืนวัตถุบางอย่างด้วยวิธีการนั้น ...
ในขณะที่ @patrick ชี้ให้เห็นแล้วไม่มี () สำหรับ js มาตรฐาน
doSome ("task") จะต้องส่งคืนวัตถุสัญญาและสัญญานั้นจะมีฟังก์ชันอยู่เสมอดังนั้นรหัสของคุณจึงเป็นเช่นนี้
promise.then(function(env) {
// logic
});
และคุณรู้ว่านี่เป็นเพียงการโทรธรรมดาสู่ฟังก์ชั่นสมาชิก
.then ส่งคืนสัญญาในฟังก์ชัน async
ตัวอย่างที่ดีจะเป็น:
var doSome = new Promise(function(resolve, reject){
resolve('I am doing something');
});
doSome.then(function(value){
console.log(value);
});
หากต้องการเพิ่มตรรกะอื่นเข้าไปคุณสามารถเพิ่มการreject('I am the rejected param')เรียกใช้ฟังก์ชันและ console.log ได้
ในกรณีthen()นี้เป็นวิธีการเรียนของวัตถุส่งกลับโดยdoSome()วิธีการ
ฟังก์ชัน ".then ()" เป็น wideley ใช้สำหรับวัตถุที่มีสัญญาในการเขียนโปรแกรม Asynchoronus สำหรับแอพ Windows 8 Store เท่าที่ฉันเข้าใจมันใช้งานได้เหมือนโทรกลับ
ค้นหารายละเอียดในเอกสารนี้ http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx
สาเหตุอาจเป็นชื่อสำหรับฟังก์ชั่นที่กำหนดอื่น ๆ
ตัวอย่างอื่น:
new Promise(function(ok) {
ok(
/* myFunc1(param1, param2, ..) */
)
}).then(function(){
/* myFunc1 succeed */
/* Launch something else */
/* console.log(whateverparam1) */
/* myFunc2(whateverparam1, otherparam, ..) */
}).then(function(){
/* myFunc2 succeed */
/* Launch something else */
/* myFunc3(whatever38, ..) */
})
ตรรกะเดียวกันโดยใช้ฟังก์ชั่นลูกศรจดชวเลข:
new Promise((ok) =>
ok(
/* myFunc1(param1, param2, ..) */
)).then(() =>
/* myFunc1 succeed */
/* Launch something else */
/* Only ONE call or statment can be made inside arrow functions */
/* For example, using console.log here will break everything */
/* myFunc2(whateverparam1, otherparam, ..) */
).then(() =>
/* myFunc2 succeed */
/* Launch something else */
/* Only ONE call or statment can be made inside arrow functions */
/* For example, using console.log here will break everything */
/* myFunc3(whatever38, ..) */
)
ฉันอายุประมาณ 8 ปีแล้วอืม ... ยังไงก็ตามฉันไม่รู้จริง ๆ ว่า () จะทำอะไร แต่ MDN อาจมีคำตอบ จริงๆแล้วฉันอาจจะเข้าใจมากกว่านี้เล็กน้อย
สิ่งนี้จะแสดงข้อมูลทั้งหมด (หวังว่า) คุณต้องการ ถ้าไม่มีใครโพสต์ลิงค์นี้ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
รูปแบบคือ contract.prototype.then () สัญญาและต้นแบบเป็นเหมือนตัวแปร แต่ไม่เหมือนตัวแปรใน javascript ฉันหมายถึงเหมือนสิ่งอื่น ๆ ไปที่นั่นเช่น navigator.getBattery (). แล้ว () ที่นี่มีอยู่จริง แต่เป็น ใช้งานบนเว็บได้แทบจะไม่แสดงสถานะเกี่ยวกับแบตเตอรี่ของอุปกรณ์ข้อมูลเพิ่มเติมและ MDN หากคุณอยากรู้