2014-12-03 40 views
0

我試圖重建基於這裏閱讀一篇文章的過程:https://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity/正確的方式來使用承諾作爲數據依賴

下面的代碼拋出一個錯誤,我現在認識到,因爲theResults.org不是一個承諾通過進程試圖時間使用theResults.org.then(),但你也許可以看到我想要的目的。我想設置好一切,這樣,而不是發號施令的控制流我只是讓子進程依賴於進入諾言的數據,但我失去了對如何獲得一些鏈接權。

驗證之後,必須創建的組織,當它存在,上下文等等等等,我知道我在這裏失去了一個重要的認識創建 - 任何人都可以指出我的步驟或語法我得到請錯? 「使用嚴格的」

var q = require('q'); 

module.exports["purchaseSchool"] = function(req, successCB, failCB) { 
    try { 
    //var purchaseData = req.body.formData; 
    var purchaseData = ""; 
    var theResults = { 
     bValidated: null, 
     org: null, 
     context: null, 
     cohort: null, 
     invoice: null, 
     bInvoiced: null, 
     bEmailed: null 
    } 
    // validate the data 
    theResults.bValidated = validatePurchaseData(purchaseData); 

    theResults.bValidated.then(function() { 
     // DEBUG: remove this 
     console.log("validated"); 
     theResults.org = createOrg(purchaseData); 
    }); 

    theResults.org.then(function() { 
     // DEBUG: remove this 
     console.log("org"); 
     theResults.context = createContext(purchaseData, theResults.org); 
    }); 

    theResults.context.then(function() { 
     // DEBUG: remove this 
     console.log("context"); 
     theResults.cohort = createCohort(purchaseData, theResults.context); 
    }); 

    theResults.cohort.then(function() { 
     // DEBUG: remove this 
     console.log("cohort"); 
     theResults.invoice = createInvoice(purchaseData); 
    }); 

    theResults.invoice.then(function() { 
     // DEBUG: remove this 
     console.log("invoice"); 
     theResults.bInvoiced = sendInvoice(theResults.invoice); 
    }); 

    theResults.bInvoiced.then(function() { 
     // DEBUG: remove this 
     console.log("invoice sent"); 
     theResults.bEmailed = sendPurchaseEmail(purchaseData); 
    }); 

    theResults.bEmailed.then(function() { 
     // DEBUG: remove this 
     console.log("emailed"); 
     successCB("Purchase Complete"); 
    }); 
    } catch (err) { 
     console.log(err); 
     console.log(err.stack); 
     failCB(); 
    } 
}; 

function validatePurchaseData(data) { 
    var defer = q.defer(); 

    setTimeout(function(){ defer.resolve(true) }, 5000); 

    return defer.promise; 
} 

function createOrg(org) { 
    var defer = q.defer(); 

    setTimeout(function(){ defer.resolve({id:"org"}) }, 5000); 

    return defer.promise; 
} 
function createContext(data, org) { 
    var defer = q.defer(); 

    setTimeout(function(){ defer.resolve({id:"context"}) }, 5000); 

    return defer.promise; 
} 
function createCohort(data, context) { 
    var defer = q.defer(); 

    setTimeout(function(){ defer.resolve({id:"cohort"}) }, 5000); 

    return defer.promise; 
} 
function createInvoice(data) { 
    var defer = q.defer(); 

    setTimeout(function(){ defer.resolve({id:"invoice"}) }, 5000); 

    return defer.promise; 
} 
function sendInvoice(invoice) { 
    var defer = q.defer(); 

    setTimeout(function(){ defer.resolve(true) }, 5000); 

    return defer.promise; 
} 
function sendPurchaseEmail(data) { 
    var defer = q.defer(); 

    setTimeout(function(){ defer.resolve(true) }, 5000); 

    return defer.promise; 
} 
+0

或承諾不,如果你命名了功能,移動出來的呼叫,並根據需要通過名稱叫他們你的代碼是乾淨多了。回調和承諾都會注入數據,所以你可以在任何地方定義處理程序。 – dandavis 2014-12-03 09:13:54

回答

0

由於通常情況下,提出這個問題幫我找到了答案。可能有更優雅的方式來做到這一點,可能使用q.all處理最終回報(我很想聽聽你對更好地做任何指針),但這裏是使工作:

'use strict' 

var q = require('q'); 

module.exports["purchaseSchool"] = function (req, successCB, failCB) { 
    // DEBUG: remove this 
    console.log("blah1"); 
    try { 
     //var purchaseData = req.body.formData; 
     var purchaseData = ""; 
     var theResults = { 
      bValidated: null, 
      org: null, 
      context: null, 
      cohort: null, 
      invoice: null, 
      bInvoiced: null, 
      bEmailed: null 
     } 
     // validate the data 
     theResults.bValidated = validatePurchaseData(purchaseData); 

     theResults.org = theResults.bValidated.then(function (bValidated) { 
      // DEBUG: remove this 
      console.log("blah2"); 
      return createOrg(purchaseData); 
     }); 

     theResults.context = theResults.org.then(function (org) { 
      return createContext(purchaseData, org); 
     }); 

     theResults.cohort = theResults.context.then(function (context) { 
      return createCohort(purchaseData, context); 
     }); 

     theResults.invoice = theResults.cohort.then(function (cohort) { 
      return createInvoice(purchaseData); 
     }); 

     theResults.bInvoiced = theResults.invoice.then(function (invoice) { 
      return sendInvoice(invoice); 
     }); 

     theResults.bEmailed = theResults.bInvoiced.then(function (bInvoiced) { 
      return sendPurchaseEmail(); 
     }); 

     theResults.bEmailed.then(function (bEmailed) { 
      successCB("Purchase Complete"); 
     }); 
    } catch (err) { 
     console.log(err); 
     console.log(err.stack); 
     failCB(); 
    } 
}; 

function validatePurchaseData(data) { 
    var defer = q.defer(); 

    setTimeout(function() { 
     defer.resolve(true) 
    }, 1000); 

    return defer.promise; 
} 

function createOrg(org) { 
    var defer = q.defer(); 

    setTimeout(function() { 
     defer.resolve({id: "org"}) 
    }, 1000); 

    return defer.promise; 
} 
function createContext(data, org) { 
    var defer = q.defer(); 

    setTimeout(function() { 
     defer.resolve({id: "context"}) 
    }, 1000); 

    return defer.promise; 
} 
function createCohort(data, context) { 
    var defer = q.defer(); 

    setTimeout(function() { 
     defer.resolve({id: "cohort"}) 
    }, 1000); 

    return defer.promise; 
} 
function createInvoice(data) { 
    var defer = q.defer(); 

    setTimeout(function() { 
     defer.resolve({id: "invoice"}) 
    }, 1000); 

    return defer.promise; 
} 
function sendInvoice(invoice) { 
    var defer = q.defer(); 

    setTimeout(function() { 
     defer.resolve(true) 
    }, 1000); 

    return defer.promise; 
} 
function sendPurchaseEmail(data) { 
    var defer = q.defer(); 

    setTimeout(function() { 
     defer.resolve(true) 
    }, 1000); 

    return defer.promise; 
} 
+2

這一切都很好,直到調用點'successCB'和'failCB' - 你可以簡單地從函數返回的承諾,然後通過回調來'then' - 但你也獲得組合性等優勢的承諾。 – 2014-12-03 11:29:09