Làm thế nào để xử lý if-else trong lời hứa sau đó?


86

Trong một số trường hợp, khi tôi nhận được giá trị trả về từ một đối tượng lời hứa, tôi cần bắt đầu hai quy trình khác nhau then()tùy thuộc vào điều kiện của giá trị, như:

promise().then(function(value){
    if(//true) {
        // do something
    } else {
        // do something 
    }
})

Tôi nghĩ có lẽ tôi có thể viết nó như sau:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        ifTruePromise().then();
    } else {
        ifFalsePromise().then();
    }
})

nhưng với điều này, tôi có hai câu hỏi:

  1. Tôi không chắc liệu có nên bắt đầu một lời hứa mới không - sau đó xử lý một lời hứa;

  2. Điều gì sẽ xảy ra nếu tôi cần hai quá trình để gọi một hàm cuối cùng? Nó có nghĩa là họ có cùng một "thiết bị đầu cuối"

Tôi đã cố gắng trả lại lời hứa mới để giữ chuỗi ban đầu như:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        // and return it
        return ifTruePromise();
    } else {
        // do something, no new promise
        // hope to stop the then chain
    }
}).then(// I can handle the result of ifTruePromise here now);

nhưng trong trường hợp này, cho dù đúng hay sai, cách tiếp theo thensẽ hoạt động.

VẬY, cách tốt nhất để xử lý nó là gì?


1
có thể đây là những gì bạn đang tìm kiếm stackoverflow.com/questions/26599798/… ?
vinayr

Câu trả lời:


60

Miễn là các hàm của bạn trả về một lời hứa, bạn có thể sử dụng phương pháp đầu tiên mà bạn đề xuất.

Fiddle bên dưới cho thấy cách bạn có thể thực hiện các đường dẫn chuỗi khác nhau tùy thuộc vào giá trị được giải quyết đầu tiên sẽ là gì.

function myPromiseFunction() {
	//Change the resolved value to take a different path
    return Promise.resolve(true);
}

function conditionalChaining(value) {
    if (value) {
        //do something
        return doSomething().then(doSomethingMore).then(doEvenSomethingMore);
    } else {
        //do something else
        return doSomeOtherThing().then(doSomethingMore).then(doEvenSomethingMore);
    }
}

function doSomething() {
    console.log("Inside doSomething function");
    return Promise.resolve("This message comes from doSomeThing function");
}

function doSomeOtherThing() {
    console.log("Inside doSomeOtherthing function");
    return Promise.resolve("This message comes from doSomeOtherThing function");
}

function doSomethingMore(message) {
    console.log(message);
    return Promise.resolve("Leaving doSomethingMore");
}

function doEvenSomethingMore(message) {
    console.log("Inside doEvenSomethingMore function");
    return Promise.resolve();
}

myPromiseFunction().then(conditionalChaining).then(function () {
    console.log("All done!");
}).
catch (function (e) {

});

Bạn cũng có thể chỉ tạo một chuỗi có điều kiện, gán lời hứa trả về cho một biến và sau đó tiếp tục thực thi các hàm nên chạy theo một trong hai cách.

function conditionalChaining(value){
    if (value) {
        //do something
        return doSomething();
    } else{
        //do something else
        return doSomeOtherThing();
    }
}

var promise = myPromiseFunction().then(conditionalChaining);

promise.then(function(value){
    //keep executing functions that should be called either way
});

4

Tôi đã viết một gói đơn giản để sử dụng lời hứa có điều kiện.

Nếu bạn muốn kiểm tra nó:

trang npm: https://www.npmjs.com/package/promise-tree

và github: https://github.com/shizongli94/promise-tree

Đáp lại các bình luận hỏi về cách gói giải quyết vấn đề:

1, Nó có hai đối tượng.

2, Đối tượng nhánh trong gói này là nơi lưu trữ tạm thời các hàm như onFulfilled và onRejected mà bạn muốn sử dụng trong then () hoặc catch (). Nó có các phương thức như then () và catch () lấy các đối số giống như các đối số trong Promise. Khi bạn chuyển một lệnh gọi lại trong Branch.then () hoặc Branch.catch (), hãy sử dụng cú pháp tương tự như Promise.then () và Promise.catch (). Sau đó, không làm gì khác ngoài việc lưu trữ các lệnh gọi lại trong một mảng.

3, Điều kiện là một đối tượng JSON lưu trữ các điều kiện và thông tin khác để kiểm tra và phân nhánh.

4, Bạn chỉ định điều kiện (biểu thức boolean) bằng cách sử dụng đối tượng điều kiện trong các lệnh gọi lại lời hứa. Sau đó, điều kiện sẽ lưu trữ thông tin bạn chuyển vào. Sau khi người dùng cung cấp tất cả thông tin cần thiết, đối tượng điều kiện sử dụng một phương thức để xây dựng đối tượng Promise hoàn toàn mới có chứa chuỗi hứa hẹn và thông tin gọi lại đã được lưu trữ trước đó trong đối tượng Branch. Một phần phức tạp nhỏ ở đây là bạn (với tư cách là người triển khai, không phải người dùng) phải giải quyết / từ chối Lời hứa mà bạn đã xây dựng lần đầu theo cách thủ công trước khi xâu chuỗi các lệnh gọi lại được lưu trữ. Điều này là do nếu không, chuỗi hứa hẹn mới sẽ không bắt đầu.

5, Nhờ có vòng lặp sự kiện, các đối tượng Branch có thể được khởi tạo trước hoặc sau khi bạn có một đối tượng Promise gốc và chúng sẽ không can thiệp vào nhau. Tôi sử dụng các thuật ngữ "cành" và "thân" ở đây vì cấu trúc giống như một cái cây.

Mã mẫu có thể được tìm thấy trên cả trang npm và github.

Nhân tiện, việc triển khai này cũng cho phép bạn có các chi nhánh trong một chi nhánh. Và các chi nhánh không nhất thiết phải ở cùng một nơi bạn kiểm tra điều kiện.


Có vẻ như bạn đang cung cấp nhận xét thay vì trả lời. Khi bạn có đủ danh tiếng, bạn sẽ có thể nhận xét về bất kỳ bài đăng nào. Cũng kiểm tra điều này tôi có thể làm gì thay thế .
thewaywewere

@thewaywewere, tôi đã thêm chi tiết triển khai đáp ứng yêu cầu của bạn.
szl1919,

0

Đây là cách tôi đã thực hiện trong lần tìm nạp () Tôi không chắc liệu đây có phải là cách đúng hay không, nhưng nó hoạt động

 fetch().then(res => res.ok ? res : false).then(res => {
    if (res) {
        //res ok
    } else {
       //res not ok
    }

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