Как тогда справиться с обещанием if-else?

86

В некоторых случаях, когда я получаю возвращаемое значение от объекта обещания, мне нужно запустить две разные then()прецессы в зависимости от условия значения, например:

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

Я думаю, может, я смогу написать это так:

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

но с этим у меня два вопроса:

  1. Я не уверен, что начинать новый процесс с потом и потом в обещании - хорошая идея;

  2. что, если мне нужно, чтобы два процесса вызывали одну функцию в последнем? Значит, у них одинаковый "терминал"

Я попытался вернуть новое обещание, чтобы сохранить исходную цепочку, например:

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

но в этом случае, верно это или ложно, thenсработает следующий .

Итак, как лучше всего с этим справиться?

Кирпич Ян
источник
1
может быть это то, что вы ищете stackoverflow.com/questions/26599798/… ?
vinayr

Ответы:

60

Пока ваши функции возвращают обещание, вы можете использовать первый предложенный вами метод.

Скрипка ниже показывает, как вы можете выбрать разные пути цепочки в зависимости от того, каким будет первое разрешенное значение.

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) {

});

Вы также можете просто создать одну условную цепочку, присвоить обещание возврата переменной, а затем продолжить выполнение функций, которые должны выполняться в любом случае.

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

Я написал простой пакет для использования условного обещания.

Если вы хотите это проверить:

Страница npm: https://www.npmjs.com/package/promise-tree

и github: https://github.com/shizongli94/promise-tree

В ответ на комментарии с вопросом, как пакет решает проблему:

1, он имеет два объекта.

2, объект Branch в этом пакете является местом временного хранения таких функций, как onFulfilled и onRejected, которые вы хотите использовать в then () или catch (). У него есть такие методы, как then () и catch (), которые принимают те же аргументы, что и аналоги в Promise. Когда вы передаете обратный вызов в Branch.then () или Branch.catch (), используйте тот же синтаксис, что и Promise.then () и Promise.catch (). Затем ничего не делайте, кроме сохранения обратных вызовов в массиве.

3. Condition - это объект JSON, в котором хранятся условия и другая информация для проверки и перехода.

4. Вы указываете условия (логическое выражение), используя объект условия в обратных вызовах обещаний. Затем Condition сохраняет переданную вами информацию. После того, как вся необходимая информация предоставлена ​​пользователем, объект условия использует метод для создания полностью нового объекта Promise, который принимает цепочку обещаний и информацию обратного вызова, ранее сохраненную в объекте Branch. Небольшая хитрость здесь заключается в том, что вы (как разработчик, а не пользователь) должны разрешить / отклонить обещание, которое вы сначала создали вручную, прежде чем связывать сохраненные обратные вызовы. Это потому, что в противном случае новая цепочка обещаний не запустится.

5. Благодаря циклу событий объекты Branch могут быть созданы как до, так и после того, как у вас есть основной объект Promise, и они не будут мешать друг другу. Я использую здесь термины «ветвь» и «стебель», потому что структура напоминает дерево.

Пример кода можно найти как на страницах npm, так и на github.

Кстати, эта реализация также позволяет иметь ветки внутри ветки. И филиалы не обязательно должны находиться в том же месте, где вы проверяете условия.

szl1919
источник
Похоже, вы вместо ответа оставляете комментарии. Когда у вас будет достаточная репутация, вы сможете комментировать любой пост. Также проверьте, что я могу сделать вместо этого .
thewaywewere
@thewaywewere, я добавил детали реализации в ответ на ваш запрос.
szl1919
0

Вот как я сделал это в моем fetch () Я не уверен, правильный ли это способ, но он работает

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

});
Сервус
источник