Tôi đã thấy mã trông giống như:
myObj.doSome("task").then(function(env) {
// logic
});
Nơi nào then()đến từ đâu?
Tôi đã thấy mã trông giống như:
myObj.doSome("task").then(function(env) {
// logic
});
Nơi nào then()đến từ đâu?
Câu trả lời:
Cách truyền thống để xử lý các cuộc gọi không đồng bộ trong JavaScript là với các cuộc gọi lại. Giả sử chúng tôi phải thực hiện ba cuộc gọi đến máy chủ, lần lượt từng cuộc gọi để thiết lập ứng dụng của chúng tôi. Với các cuộc gọi lại, mã có thể trông giống như sau (giả sử hàm xhrGET để thực hiện cuộc gọi máy chủ):
// 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
});
});
});
Trong ví dụ này, trước tiên chúng ta tìm nạp cấu hình máy chủ. Sau đó, dựa vào đó, chúng tôi tìm nạp thông tin về người dùng hiện tại và cuối cùng nhận được danh sách các mục cho người dùng hiện tại. Mỗi cuộc gọi xhrGET có chức năng gọi lại được thực thi khi máy chủ phản hồi.
Bây giờ tất nhiên chúng ta càng có nhiều mức lồng nhau, mã càng khó đọc, gỡ lỗi, bảo trì, nâng cấp và về cơ bản làm việc với. Điều này thường được gọi là địa ngục gọi lại. Ngoài ra, nếu chúng ta cần xử lý lỗi, chúng ta cần chuyển một hàm khác cho mỗi lệnh gọi xhrGET để nói với nó những gì nó cần làm trong trường hợp có lỗi. Nếu chúng tôi muốn chỉ có một trình xử lý lỗi phổ biến, điều đó là không thể.
API Promise được thiết kế để giải quyết vấn đề lồng nhau này và vấn đề xử lý lỗi.
API Promise đề xuất như sau:
promiseđối tượng.promiseđối tượng sẽ có một thenhàm có thể lấy hai đối số, một hàm success
xử lý và một hàm errorxử lý.thenhàm sẽ chỉ được gọi một lần , sau khi tác vụ không đồng bộ kết thúc.thenchức năng cũng sẽ trở lại một promise, để cho phép chaining nhiều cuộc gọi.value, sẽ được chuyển đến hàm tiếp theo dưới dạng một argumentchuỗi trong promises.promise(thực hiện một yêu cầu không đồng bộ khác), thì trình xử lý tiếp theo (thành công hoặc lỗi) sẽ chỉ được gọi sau khi yêu cầu đó kết thúc.Vì vậy, mã ví dụ trước có thể dịch sang một cái gì đó như sau, sử dụng lời hứa và $httpdịch vụ (trong 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
}
);
Tuyên truyền thành công và lỗi
Chaining hứa hẹn là một kỹ thuật rất mạnh mẽ cho phép chúng ta thực hiện rất nhiều chức năng, như có một dịch vụ thực hiện cuộc gọi máy chủ, thực hiện một số xử lý hậu kỳ của dữ liệu và sau đó trả lại dữ liệu đã xử lý cho bộ điều khiển. Nhưng khi chúng tôi làm việc với
promisecác chuỗi, có một vài điều chúng tôi cần ghi nhớ.
Hãy xem xét promisechuỗi giả thuyết sau với ba lời hứa, P1, P2 và P3. Mỗi người promisecó một trình xử lý thành công và một trình xử lý lỗi, vì vậy S1 và E1 cho P1, S2 và E2 cho P2 và S3 và E3 cho P3:
xhrCall()
.then(S1, E1) //P1
.then(S2, E2) //P2
.then(S3, E3) //P3
Trong dòng chảy thông thường của mọi thứ, khi không có lỗi, ứng dụng sẽ chảy qua S1, S2 và cuối cùng là S3. Nhưng trong cuộc sống thực, mọi thứ không bao giờ suôn sẻ như vậy. P1 có thể gặp lỗi hoặc P2 có thể gặp lỗi, kích hoạt E1 hoặc E2.
Hãy xem xét các trường hợp sau:
• Chúng tôi nhận được phản hồi thành công từ máy chủ trong P1, nhưng dữ liệu được trả về là không chính xác hoặc không có dữ liệu có sẵn trên máy chủ (nghĩ rằng mảng trống). Trong trường hợp như vậy, đối với lời hứa P2 tiếp theo, nó sẽ kích hoạt trình xử lý lỗi E2.
• Chúng tôi nhận được lỗi cho lời hứa P2, kích hoạt E2. Nhưng bên trong trình xử lý, chúng tôi có dữ liệu từ bộ đệm, đảm bảo ứng dụng có thể tải như bình thường. Trong trường hợp đó, chúng tôi có thể muốn đảm bảo rằng sau khi gọi E2, S3.
Vì vậy, mỗi lần chúng ta viết thành công hay xử lý lỗi, chúng ta cần thực hiện một cuộc gọi bằng cách đưa ra chức năng hiện tại của mình, đây có phải là lời hứa thành công hay thất bại cho người xử lý tiếp theo trong chuỗi hứa hẹn không?
Nếu chúng ta muốn kích hoạt trình xử lý thành công cho lời hứa tiếp theo trong chuỗi, chúng ta có thể trả về một giá trị từ thành công hoặc trình xử lý lỗi
Mặt khác, nếu chúng ta muốn kích hoạt trình xử lý lỗi cho lời hứa tiếp theo trong chuỗi, chúng ta có thể thực hiện điều đó bằng cách sử dụng một deferredđối tượng và gọi reject()phương thức của nó
Bây giờ đối tượng trì hoãn là gì?
Các đối tượng bị trì hoãn trong jQuery đại diện cho một đơn vị công việc sẽ được hoàn thành sau này, thường là không đồng bộ. Khi đơn vị công việc hoàn thành,
deferredđối tượng có thể được đặt thành giải quyết hoặc thất bại.Một
deferredđối tượng chứa mộtpromiseđối tượng. Thông quapromiseđối tượng, bạn có thể chỉ định những gì sẽ xảy ra khi đơn vị công việc hoàn thành. Bạn làm như vậy bằng cách đặt các hàm gọi lại trênpromiseđối tượng.
Các đối tượng bị trì hoãn trong Jquery: https://api.jquery.com/jquery.deferred/
Các đối tượng bị trì hoãn trong AngularJs: https://docs.angularjs.org/api/ng/service/ $ q
Hàm () có liên quan đến "Lời hứa Javascript" được sử dụng trong một số thư viện hoặc khung như jQuery hoặc AngularJS.
Một lời hứa là một mẫu để xử lý các hoạt động không đồng bộ. Lời hứa cho phép bạn gọi một phương thức gọi là "sau đó" cho phép bạn chỉ định (các) chức năng sẽ sử dụng làm cuộc gọi lại.
Để biết thêm thông tin, hãy xem: http://wildermuth.com/2013/8/3/JavaScript_Promises
Và đối với những lời hứa của Angular: http : // nékaufman.com/blog/2013/09/09/USE- angularjs-promises/
A promise can only succeed or fail oncevàIf a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called
Theo hiểu biết của tôi, không có một then()phương pháp tích hợp nào javascript(tại thời điểm viết bài này).
Dường như bất cứ điều gì doSome("task")đang trở lại đều có một phương thức được gọi then.
Nếu bạn đăng nhập kết quả trả về của doSome()bàn điều khiển, bạn sẽ có thể thấy các thuộc tính của những gì được trả về.
console.log( myObj.doSome("task") ); // Expand the returned object in the
// console to see its properties.
CẬP NHẬT (Kể từ ECMAScript6) : -
Các .then()chức năng đã được bao gồm để javascript thuần.
Từ tài liệu Mozilla tại đây ,
Phương thức then () trả về một Promise. Phải có hai đối số: hàm gọi lại cho các trường hợp thành công và thất bại của Lời hứa.
Đối tượng Promise, lần lượt, được định nghĩa là
Đối tượng Promise được sử dụng cho các tính toán hoãn lại và không đồng bộ. Một lời hứa đại diện cho một hoạt động chưa hoàn thành, nhưng dự kiến trong tương lai.
Đó là, các Promisehành vi như một trình giữ chỗ cho một giá trị chưa được tính toán, nhưng sẽ được giải quyết trong tương lai. Và .then()chức năng được sử dụng để liên kết các chức năng sẽ được gọi trên Promise khi nó được giải quyết - là thành công hoặc thất bại.
.then, nhưng những lời hứa bản địa hiện đang có trong ES6: html5rocks.com/en/tutorials/es6/promises
Đây là một điều tôi làm cho bản thân mình để làm rõ mọi thứ hoạt động như thế nào. Tôi đoán những người khác cũng có thể tìm thấy ví dụ cụ thể này hữu ích:
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>
sau đó là một ngăn xếp gọi lại phương thức có sẵn sau khi một lời hứa được giải quyết, nó là một phần của thư viện như jQuery nhưng bây giờ nó có sẵn trong JavaScript gốc và dưới đây là phần giải thích chi tiết về cách thức hoạt động của nó
Bạn có thể thực hiện Lời hứa bằng JavaScript nguyên gốc: giống như có lời hứa trong jQuery, Mọi lời hứa có thể được xếp chồng lên nhau và sau đó có thể được gọi bằng Giải quyết và Từ chối cuộc gọi lại, Đây là cách bạn có thể xâu chuỗi các cuộc gọi không đồng bộ.
Tôi đã rẽ nhánh và Chỉnh sửa từ Tài liệu MSDN về trạng thái sạc pin ..
Những gì nó làm là cố gắng tìm hiểu xem máy tính xách tay hoặc thiết bị của người dùng đang sạc pin. sau đó được gọi và bạn có thể làm bài thành công của bạn.
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}`)
})
Định nghĩa :: sau đó là một phương thức được sử dụng để giải quyết các cuộc gọi lại không đồng bộ
điều này được giới thiệu trong ES6
Vui lòng tìm tài liệu phù hợp tại đây Es6 Promising
thennguồn gốc từ đâu và cách thức hoạt động. Bạn nên cải thiện câu trả lời của bạn để cung cấp những chi tiết đó.
Tôi nghi ngờ doSome trả về cái này, đó là myObj, cũng có một phương thức sau đó. Phương pháp chuẩn chuỗi ...
nếu doSome không trả về cái này, là đối tượng mà doSome được thực thi, hãy yên tâm rằng nó sẽ trả về một số đối tượng bằng phương thức sau đó ...
như @patrick chỉ ra, không có () cho js tiêu chuẩn
doSome ("tác vụ") phải trả về một đối tượng lời hứa và lời hứa đó luôn có chức năng sau đó. Vì vậy, mã của bạn giống như thế này
promise.then(function(env) {
// logic
});
và bạn biết đây chỉ là một cuộc gọi thông thường đến chức năng thành viên.
.then trả về một lời hứa trong chức năng async.
Ví dụ tốt sẽ là:
var doSome = new Promise(function(resolve, reject){
resolve('I am doing something');
});
doSome.then(function(value){
console.log(value);
});
Để thêm logic khác vào nó, bạn cũng có thể thêm lệnh reject('I am the rejected param')gọi hàm và console.log nó.
Trong trường hợp then()này là một phương thức lớp của đối tượng được trả về bởi doSome()phương thức.
Hàm ".then ()" là wideley được sử dụng cho các đối tượng được hứa hẹn trong lập trình Asynchoronus cho Ứng dụng Windows 8 Store. Theo như tôi hiểu thì nó hoạt động theo cách nào đó giống như một cuộc gọi lại.
Tìm chi tiết trong Tài liệu này http://msdn.microsoft.com/en-us/l Library / windows / apps / hh700330.aspx
Nguyên nhân cũng có thể là tên cho bất kỳ chức năng được xác định nào khác.
Một vi dụ khac:
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, ..) */
})
Logic tương tự sử dụng chức năng mũi tên tốc ký:
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, ..) */
)
Tôi trễ khoảng 8 năm, dù sao thì ... dù sao thì tôi cũng không biết sau đó () làm gì nhưng có lẽ MDN có thể có câu trả lời. Trên thực tế, tôi thực sự có thể hiểu nó nhiều hơn một chút.
Điều này sẽ cho bạn thấy tất cả các thông tin (hy vọng), bạn cần. Trừ khi ai đó đã đăng liên kết này. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
Định dạng là prom.prototype.then () Lời hứa và nguyên mẫu là loại biến giống như biến nhưng không giống biến trong javascript, ý tôi là giống như những thứ khác đến đó như navigator.getBattery (). Then () trong đó cái này thực sự tồn tại nhưng là Hầu như không được sử dụng trên web, ứng dụng này hiển thị trạng thái về pin của thiết bị, thêm thông tin và nhiều thông tin khác về MDN nếu bạn tò mò.