【问题标题】:Returned value from promise is not what is expected承诺的返回值不是预期的
【发布时间】:2014-11-24 05:12:26
【问题描述】:

我有一些逻辑,我正在尝试构建一个“人”对象,并且我有一个名为 getProvider 的方法,我基本上是从 mongo 获取提供程序并将其分配给 person.provider

由于对 mongo 的调用是异步的,我正在尝试使用 Promise。除了我的.then 方法外,我在任何地方记录的值似乎都是正确的。它显示{"source": {}},我不知道为什么。

这是我的输出:

data = 
MYPROVIDER
provider = 
MYPROVIDER
after addProvider
{"source":{}}


...
configDone.promise.then(function () {
    return addProvider();
}).then(function() {
    console.log('after addProvider');
    console.log(JSON.stringify(people[0].provider)); // SHOWS {"source": {}}. WHY IS IT DOING THIS?
    callback(null, people);
}).fail(function (err) {
    callback(err);
});


function addProvider() {

    var promises = [];

    people.forEach(function(person){
        promises.push(person.provider = getProvider(person.id, db));
    });

    return Q.all(promises).spread(function(provider) {
        console.log('provider = ');
        console.log(provider); // SHOWS CORRECT PROVIDER HERE
    });
}

// Gets a provider for a specific person id
var getProvider = function(id, db) {

    var def = Q.defer();

    db.collection('providerLists').findOne({id: id}, function (err, data) {

        if (err) {
            def.reject(err);
        } else {
            console.log('data = ');
            console.log(data.ListName);  // SHOWS CORRECT VALUE
            def.resolve(data.ListName);
        }
    });

    return def.promise;
}

【问题讨论】:

    标签: javascript node.js asynchronous q


    【解决方案1】:

    people[0].provider 应该指向一个已解决的承诺。如果您将then 处理程序附加到它,您将看到预期的提供程序值:

    people[0].provider.then(function(provider) {
      console.log(JSON.stringify(provider);
    });
    

    如果您想让提供者成为 people 数组中每个人的值,您可以按如下方式更新您的 addProvider 函数:

    function addProvider() {
    
    var promises = [];
    
    people.forEach(function(person){
        promises.push(getProvider(person.id, db)
          .then(function(provider) {
            person.provider = provider;
          });
    });
    
    return Q.all(promises).spread(function(provider) {
        console.log('provider = ');
        console.log(provider); // SHOWS CORRECT PROVIDER HERE
    });
    }
    

    【讨论】:

    • 我不希望提供者出现在人员数组中,因为每个人都有一个特定的提供者。那么我将如何循环并以这种方式分配呢?
    • configDone.promise.then(function () { return addProvider(); }).then(function() { console.log('after addProvider'); console.log(JSON.stringify(patients[0].provider)); patients[0].then(function(provider) { console.log(provider); }) callback(null, people); }).fail(function (err) { callback(err); }); 这给出了错误Error: TypeError: Object #<Object> has no method 'then'
    • @Catfish:你需要使用patients[0].provider.then(function(provider) { console.log(provider); }) - 单个患者确实不是一个承诺。
    • 好的,这适用于@Bergi 的编辑。我真的不喜欢这种风格的外观。有没有办法可以重构我的addProvider 方法,以便我可以在该方法中而不是在我的config.promise.then 块中实际设置person.provider
    • @Catfish 添加了方法,在该方法中,您拥有每个人的 provider 属性,作为对我的回答的承诺调用的结果。
    猜你喜欢
    • 2017-04-02
    • 1970-01-01
    • 2020-12-23
    • 2015-10-30
    • 1970-01-01
    • 2019-06-09
    • 2016-10-11
    • 2017-11-24
    相关资源
    最近更新 更多