2016-09-29 131 views
-3

我開始學習使用loopback和jsforce的諾言,並且無法處理這個問題;我無法將狀態變量返回給cb()函數。 基本上我想連接salesforce並通過JSforce獲取數據並通過回送將其寫入數據庫。然後想要在遠程調用後調用創建/更新/錯誤記錄到客戶端。如何返回承諾內的狀態?

我與迴環通過使用Node.js的& Express.js 開發我使用JSforce庫連接的Salesforce

我怎樣才能解決呢?

這裏是我的代碼:

module.exports = function(Contact) { 
    var jsforce = require('jsforce'); 
    var async = require("async"); 
    var lr = require('lr.js'); 

    Contact.ImportContacts = function(cb) { 
    // Salesforce Projects List 
    var sf_projects = []; 
    //Salesforce Conn String 
    var conn = lr.SalesforceConn(); 
    conn.apex.get("/Contact/", function(err, res) { 
     var status = { 
     "Created": [], 
     "Updated": [], 
     "Error": "" 
     }; 
     if (err) console.log(err); 

     sf_projects = res; 
     // Clear result 
     status.Created.length = 0; 
     status.Updated.length = 0; 
     status.Error = ""; 

     if (sf_projects != undefined) { 
     async.eachSeries(sf_projects, function(contact, callback) { 
      Contact.findOrCreate({ 
       where: { 
       co_SalesforceID: contact.Id 
       } 
      }, { 
       co_Name: contact.FirstName, 
       co_Surname: contact.LastName, 
       co_Salutation: contact.Salutation, 
       co_Title: contact.Title, 
       co_Department: contact.Department, 
       co_Email: contact.Email, 
       co_PhonePersonal: contact.HomePhone, 
       co_PhoneWork: contact.Phone, 
       co_PhoneCell: contact.MobilePhone, 
       co_Description: contact.Description, 
       co_SalesforceID: contact.Id 
      }, 
      function(err, cntct, created) { 
       if (err) console.log(err); 
       if (created) { 
       status.Created.push(cntct.id); 
       console.log("Contact created. SalesForeID: " + 
        cntct.co_SalesforceID + 
        " ContactName: " + 
        lr.isDefined(cntct.co_Salutation) + " " + 
        lr.isDefined(cntct.co_Name) + " " + 
        lr.isDefined(cntct.co_Surname)); 
       } else { 
       Contact.replaceById(cntct.id, { 
        co_Name: contact.FirstName, 
        co_Surname: contact.LastName, 
        co_Salutation: contact.Salutation, 
        co_Title: contact.Title, 
        co_Department: contact.Department, 
        co_Email: contact.Email, 
        co_PhonePersonal: contact.HomePhone, 
        co_PhoneWork: contact.Phone, 
        co_PhoneCell: contact.MobilePhone, 
        co_Description: contact.Description, 
        co_SalesforceID: contact.Id 
        }, 
        false, 
        function(err, obj) { 
        if (err) console.log(err); 
        status.Updated.push(obj.id); 
        console.log("Contact updated. SalesForeID: " + 
         obj.co_SalesforceID + " ContactName: " + 
         lr.isDefined(obj.co_Salutation) + " " + 
         lr.isDefined(obj.co_Name) + " " + 
         lr.isDefined(obj.co_Surname)); 
        }); 
       } 
      }); 
      callback(err); 
     }, function(err) { 
      if (err) console.error(err); 
     }); 
     } else { 
     console.log("Salesforce Connection Error!"); 
     status.Error = "Salesforce Connection Error"; 
     } 
     return Promise.resolve(status); 
    }).then(function(end) { 
     cb(null, end); 

    }).catch(function(err) { 
     if (err) console.log(err); 
    }); 
    }; 
    Contact.remoteMethod(
    'ImportContacts', { 
     returns: { 
     arg: 'result', 
     type: 'string' 
     }, 
     http: { 
     path: '/importContacts', 
     verb: 'get' 
     } 
    } 
); 
}; 
+0

你想從那裏究竟這個牆上的文字內回覆? – deceze

+0

我想從conn.apex.get()中返回狀態變量,並將其賦予給cb()函數 – canerce

+0

也許你可以嘗試類似的方式解決:解決方案({status:status,callback:cb}) ; 並且在隨後塊: 。然後(函數(端){ end.callback(NULL,end.status); })進行更改應用凍結和應用後 – 1337

回答

1

這不是完全清楚什麼都問,你不包括您solve()功能,可能是重要的在這裏,所以我只能給你一些提示。

你有這樣的事情:

}).then(function(end) { 
    cb(null, end); 
}).catch(function(err) { 
    if (err) console.log(err); 
}); 

第一部分(then)表明cb()回調發生錯誤作爲第一個參數和值作爲第二個參數,節點回調的通用慣例以下。

但是,在第二部分(catch)中,您不會調用帶有錯誤的回調。此外,if (err)是多餘的,因爲在catch處理程序中總會有錯誤,除非solve()函數返回被拒絕的承諾,並指定falsenull作爲拒絕原因 - 即使如此,無論拒絕原因是什麼,回調都應始終在出現錯誤的情況下調用:

}).then(function(end) { 
    cb(null, end); 
}).catch(function(err) { 
    console.log(err); 
    cb(err); 
}); 

這樣你就不會得到回調永遠不會被調用並等待的情況。當您將承諾與傳統回調混合使用時,您必須牢記幾件事:

任何獲取回調作爲參數的函數都應該確保調用此回調函數,並且它只被調用一次。這是您作爲功能作者確保的責任。在錯誤的情況下,你應該運行:

callback(error); 

,並在成功的情況下,你應該叫:

callback(null, data); 

這樣,當操作完成的callback可以知道它是否與完成通過測試其第一個參數是成功還是失敗:

function (err, data) { 
    if (err) { 
    console.log('Error:', err); 
    } else { 
    console.log('Success:', data); 
    } 
} 

服用回調的函數的整個調用通常是:

functionTakingCallback('some', 'arguments', function (err, data) { 
    if (err) { 
    console.log('Error:', err); 
    } else { 
    console.log('Success:', data); 
    } 
}); 

在另一方面,如果該函數返回一個承諾,你用這樣的:

functionReturningPromise('some', 'arguments') 
.then(function (data) { 
    console.log('Success:', data); 
}) 
.catch(function (err) { 
    console.log('Error:', err); 
}); 

沒有必要在這種情況下,測試err

回調應該總是被調用一次。承諾總是應該最終解決或拒絕。用法不同,主叫方和被叫方的責任是不同的。當你將這兩種風格混合在一起時 - 那些採用傳統的節點式回調函數和返回承諾的函數 - 那麼你必須小心這些差異。

可以轉換有時是需要回調函數的函數返回使用像藍鳥及其在整個代碼庫中所有的異步功能promisify()promisifyAll()有一致的API庫的承諾。請參閱:

你可以看到一些其他的答案,我解釋回調和承諾,以及如何更詳細一起使用它們之間的區別,這可能會對你有所幫助在這種情況下:

+0

嗨@rsp感謝關於錯誤控制和回調用法。我添加了缺少的代碼,對此抱歉:/在返回時更改了一些代碼。解決=> Promise.resolve 我將改變代碼並立即嘗試 – canerce