2017-08-25 56 views
1

我试图在列表中创建MailChimp中的合并域,如果它们不存在的话。如果它们不存在,我希望它们被推到承诺列表中,我使用promises.all来确保已添加所有必要的列表项目。js诺言的问题(蓝鸟)

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

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 
} 

注意:我使用请求承诺提出我的请求,因此它们已被promisified。

+0

你对'allProductIDPromises'做了什么? – trincot

+0

allProductIDPromises.push( getMergeFieldsPromise, getMergeNumPromise, updateMergeFields ) Promise.all(allProductIDPromises) 。然后(函数() – cclos

+0

我编辑了自己的问题,以提高压痕{即正在运行无序的功能}你的代码,我也删除了只会分散注意力的短语(这里的人们想从前几句中理解你的问题,所以跳过所有的介绍,以及你是如何被难住的等等)。你可以调用'Promise.all'吗?还要注意,你在你的问题中提到了'promises.all',而不是'Promise.all'。 – trincot

回答

0

then回调getMergeFieldsPromise不返回任何东西,所以一旦getMergeFieldsPromise解决了,它不会等待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链接,所以您只需执行最后一个承诺的then

updateMergeFields.then(function(addedMergeFields) { 
    // ... all is ready now. 
} 

最后,阅读有关Promise constructor anti-pattern,它使用的是几次:你不应该使用new Promise时候,其实你可以返回一个承诺(例如return rp())。

+0

非常感谢你!现在你已经解释了这个意思了!我会upvote你,但我没有声誉:( – cclos