2016-02-01 2 views
1

У меня есть код Node.js обещания, что выглядит примерно так:Каков наилучший способ написать читаемый код с помощью обещаний?

function myFunc(data) { 
    Q(data).then(function(data) { 
    return getPromise1(globalVar).then(function(res1a) { 
     return getPromise2(JSON.parse(param2)).then(function(res2a) { 
     return doStuff(); 
     }).then(function(res2b) { 
     return getPromise3(data).then(function(res3a) { 
      return getPromise4.then(function(res4a) { 
      // more stuff 
      }) 
     }) 
     }) 
    }) 
    }) 
}) 

Как вы можете видеть, этот код не очень читаемый. Есть лучший способ сделать это?

+2

Возможно, вам не нужно вставлять его. Вероятно, вы можете сделать a(), затем (...). Then (...). Then (...) '. – jfriend00

ответ

1

Одна из целей обещаний, помимо разделения параметров данных из параметров потока управления, на самом деле решила эту проблему с огромными треугольными блоками кода.

function myFunc(data) { 
    Q(data).then(function(data) { 
    return getPromise1(globalVar); 
    }).then(function(res1a) { 
    return getPromise2(JSON.parse(param2)); 
    }).then(function(res2a) { 
    return doStuff(); 
    }).then(function(res2b) { 
    return getPromise3(data); 
    }).then(function(res3a) { 
    return getPromise4; 
    }).then(function(res4a) { 
    // more stuff 
    }) 
} 

Теперь, единственная причина, вы когда-нибудь понадобится, чтобы гнездиться обещание, если вам нужно использовать данные, возвращаемые обещание в функции не сразу после этого. См. Ниже:

doAsyncA().then(function(x) { 
    doAsyncB().then(function(y) { 
    doSyncUsingBothReturns(x, y); 
    }) 
}) 
1

В вашем примере это помогло бы использовать лямбда-выражения:

Q(data) .then(data => getPromise1(globalVar) .then(re1a => getPromise2(JSON.parse(param2)

и так далее. без вложенности и в этом стиле, он выглядит намного меньше, как обратный вызов ад :)

3

Если вам не нужен все результаты сразу, просто перестать относиться к обещаниям, как обратные вызовы:

function myFunc(data) { 
    Q(data).then(function(data) { 
    return getPromise1(globalVar); 
    }).then(function(res1a) { 
    return getPromise2(JSON.parse(param2)); 
    }).then(function(res2a) { 
    return doStuff(); 
    }).then(function(res2b) { 
    return getPromise3(data); 
    }).then(function(res3a) { 
    return getPromise4; 
    }).then(function(res4a) { 
    // more stuff 
    }) 
}) 

Если вы делать, то вы можете попробовать coroutines данную поддержку функции генератора (Q, вероятно, имеет что-то для этого, но вот Bluebird путь):

var myFunc = bluebird.coroutine(function* myFunc(data) { 
    var res1a = yield getPromise1(globalVar); 
    var res2a = yield getPromise2(JSON.parse(param2)); 
    var res2b = yield doStuff(); 
    var res3a = yield getPromise3(data); 
    var res4a = yield getPromise4; 

    // more stuff 
}) 

или synchronous inspection:

function myFunc(data) { 
    var res1a = getPromise1(globalVar); 
    var res2a = res1a.then(function() { 
    yield getPromise2(JSON.parse(param2)); 
    }); 
    var res2b = res2a.then(function() { 
    // feel free to use res1a.value() here; 
    // you know that it has to have been resolved 
    doStuff(); 
    }); 

    // … 

    return res4a; 
} 
Смежные вопросы