2017-08-25 66 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