2016-09-29 128 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