js promises麻烦(蓝鸟)

时间:2017-08-25 06:48:03

标签: javascript node.js promise mailchimp bluebird

我正在尝试从列表中创建合并字段(如果它们尚不存在)。如果它们不存在,我希望将它们推送到promises列表,我使用promises.all来确保添加了所有必需的列表项。

这不行。我究竟做错了什么?

var productDict = []

var getMergeNumPromise = new Promise( 
    function(resolve, reject) {
        // call to mailchimp to get the number of merge fields
        rp({
            uri: MAILCHIMP_MERGEFIELDS_URI, 
            qs:{count:1}, 
            json:true, 
            headers:MAILCHIMP_HEADER
        })
        .then(function( mergeFieldList ) {
            console.log("total items: " + mergeFieldList.total_items)
            resolve(mergeFieldList.total_items)
        })
        .catch(function(err) {
            console.log("error getting merge field count: " + err)
            reject(err)
        })
    }
)

var getMergeFieldsPromise = new Promise( 
    function( resolve, reject ) {
        getMergeNumPromise.then(function( total, err ){
            //gets just the name and tag for all merge fields in the list
            rp({
                uri: MAILCHIMP_MERGEFIELDS_URI, 
                qs:{
                    count: total,
                    fields: "merge_fields.tag,merge_fields.name"
                },
                headers: MAILCHIMP_HEADER
            })
            .then(function( fullFieldList ) {
                console.log("FULL FIELD BODY" + fullFieldList)
                var body = JSON.parse(fullFieldList)
                resolve(body.merge_fields)
            })
            .catch(function(err){
                console.log("error getting fields: " + err)
                reject(err)
            })
        })
    }
)

function addMergeField (prodName , dictPos) {
    return new Promise (
        function(resolve, reject) {
            fieldBody = { name : prodName , type : "number"}

            //post request to make the new merge field
            rp({
                method: "POST", 
                uri: MAILCHIMP_MERGEFIELDS_URI, 
                json: true, 
                headers: MAILCHIMP_HEADER, 
                body: fieldBody
            })
            .then(function(body) {
                //update product dictionary
                productDict[dictPos] = {tag : body.tag, name : body.name}
                console.log("MERGE FIELD RESPONSE " + JSON.stringify(body))
                resolve(body)
            })
           .catch(function(err) {
                console.log("error creating merge field for product id: " + err)
                reject(err)
            })
        }
    )
}

var updateMergeFields = getMergeFieldsPromise.then( 
    function( mergeFieldList ) {
        // resolved ids keeps track of ids that have already been added
        var resolvedIDS = {}
        //holds result of find to look for product ids
        var foundMCMatch
        // holds productIDS[i]
        var product
        //console.log("merge field list" + JSON.stringify(mergeFieldList))

        for(var i = 0; i < productIDS.length; i++) {
            console.log("checking if product id " + productIDS[i] + "exists")
            product = productIDS[i]
            // tries to find a match to see if fields are already in mailchimp
            foundMCMATCH = mergeFieldList.find(x => x.name == product)

            if(foundMCMATCH) {
                console.log("foundMCMATCH" + JSON.stringify(foundMCMATCH))

                //updates product dict with matching tag/name from mailchimp
                productDict[i] = {
                    tag : foundMCMATCH.tag, 
                    name : foundMCMATCH.name
                }
                //console.log("PRODUCT DICT " + JSON.stringify(productDict))
            }

            //if field isn't on mailchimp
            else if (!resolvedIDS[product])
            {
                resolvedIDS[product] = true

                // adds product id as merge field becasue it doesn't exist
                allProductIDPromises.push(
                    addMergeField(product,i)
                )
            }
        }
    }
)

allProductIDPromises.push( getMergeFieldsPromise, getMergeNumPromise, updateMergeFields ) 
Promise.all(allProductIDPromises) 
.then(function() { 
    //function here that's running out of order
}

注意:我正在使用请求承诺来发布我的帖子请求,因此它们已被宣传。

1 个答案:

答案 0 :(得分:0)

then的{​​{1}}回调未返回任何内容,因此一旦getMergeFieldsPromise解决,它就不会等待getMergeFieldsPromise承诺,而是立即解析(使用{ {1}}承诺的价值)。

要解决此问题,请在addMergeField回调中设置undefined个本地变量并在其上调用allProductIDPromises,然后返回

then

然后,你应该删除它:

Promise.all

...由于您的三个主要承诺已与var updateMergeFields = getMergeFieldsPromise.then( function( mergeFieldList ) { // **** make the array of promises local to this function var allProductIDPromises = []; // resolved ids keeps track of ids that have already been added var resolvedIDS = {} //holds result of find to look for product ids var foundMCMatch // holds productIDS[i] var product //console.log("merge field list" + JSON.stringify(mergeFieldList)) for(var i = 0; i < productIDS.length; i++) { console.log("checking if product id " + productIDS[i] + "exists") product = productIDS[i] // tries to find a match to see if fields are already in mailchimp foundMCMATCH = mergeFieldList.find(x => x.name == product) if(foundMCMATCH) { console.log("foundMCMATCH" + JSON.stringify(foundMCMATCH)) //updates product dict with matching tag/name from mailchimp productDict[i] = { tag : foundMCMATCH.tag, name : foundMCMATCH.name } //console.log("PRODUCT DICT " + JSON.stringify(productDict)) } //if field isn't on mailchimp else if (!resolvedIDS[product]) { resolvedIDS[product] = true // adds product id as merge field becasue it doesn't exist allProductIDPromises.push( addMergeField(product,i) ) } } // **** call Promise.all here, and return it return Promise.all(allProductIDPromises); } ) 链接,因此您只需在最后一个上执行allProductIDPromises.push( ... )

then

最后,请阅读您多次使用的Promise constructor anti-pattern:您不应该使用then,实际上您可以返回一个承诺(例如updateMergeFields.then(function(addedMergeFields) { // ... all is ready now. } )。

相关问题