使用承诺作为数据依赖项的正确方法

Proper way to use promises as data dependencies

本文关键字:方法 数据依赖 承诺      更新时间:2023-09-26

我正在尝试根据阅读此处的文章重建一个过程:https://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity/

下面的代码抛出了一个错误,我现在意识到,因为当进程尝试使用 theResults.org.then() 时 theResults.org 这不是一个承诺,但你可能会看到我想要实现的目标。我想设置所有内容,以便我只是使子流程依赖于进入承诺的数据,而不是指示控制流,但我迷失了如何正确链接。

验证后,必须创建组织,然后当它存在时,创建上下文等。我知道我在这里缺少一个关键的理解 - 任何人都可以向我指出我弄错的步骤或语法吗? "使用严格"

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

通常情况下,提出这个问题帮助我找到了答案。可能有更优雅的方法可以做到这一点,也许使用 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;
}