2016-09-29 3 views
-3

Я начал изучать обещание с loopback и jsforce и не мог справиться с этой проблемой; Я не смог вернуть статус var внутри обещания функции cb(). В основном я хочу подключить salesforce и получить данные через JSforce и записать его в db через loopback. Затем вы хотите вернуть созданные/обновленные/записи ошибок клиенту после вызова удаленного мотогона.Как я могу вернуть статус внутри обещания?

Я разрабатываю с Loopback с помощью использования 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

Возможно, вы можете попробовать что-то вроде этого для своего решения: solve ({status: status, callback: cb}) ; и что в вашем блоке затем: .then (функция (окончание) { end.callback (нуль, 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() не возвращает отклоненное обещание с false или null, указанное в качестве причины отклонения, - и даже тогда, независимо от причины отклонения, обратный вызов всегда должен вызываться в случае ошибки:

}).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 в этом случае.

Обратные вызовы всегда следует называть ровно один раз. В любом случае обещания всегда должны быть разрешены или отвергнуты. Использование различно, и ответственность как вызывающего, так и вызываемого абонента различна. Когда вы смешиваете эти два стиля - функции, которые принимают традиционные обратные вызовы в стиле Node и функции, которые возвращают обещания, - тогда вы должны быть осторожны с этими различиями.

Иногда вы можете преобразовывать функции, которые принимают обратные вызовы для функций, возвращающих обещания с использованием библиотек, таких как Bluebird, и его promisify() и promisifyAll(), чтобы иметь согласованный API для всех ваших асинхронных функций во всей кодовой базе. См:

Вы можете увидеть некоторые другие ответы, где я объясняю разницу между обратными вызовами и обещаниями, и как использовать их в более подробно, что может быть полезно для вас в этом случае:

+0

привет @rsp спасибо за ошибки управления и обратного вызова. Я добавил недостающий код, сожалею об этом:/изменил код при возврате. solve => Promise.resolve Я изменю код и попробую сейчас – canerce