2016-04-05 34 views
0

我有一個小問題,這個腳本作品完美,有一個問題,「runTenant」方法沒有返回一個承諾(需要從「所有()」解決節點返回BluebirdJS答應

此代碼:

Promise.resolve(runTenant(latest)).then(function() { 
    end(); 
}); 

調用此代碼:

function runTenant(cb) { 
    return new Promise(function() { 
    //global var 
    if (!Tenant) { 
     loadCoreModels(); 
     Tenant = bookshelf.core.bs.model('Tenant'); 
    } 

    new Tenant().fetchAll() 
     .then(function(tenants) { 

     if (tenants.models.length == 0) { 
      return; 
     } else { 
      async.eachSeries(tenants.models, function(tenant, next) { 

      var account = tenant.attributes; 
      Promise.resolve(db_tenant.config(account)).then(function(knex_tenant_config) { 
       if (knex_tenant_config) { 
       db_tenant.invalidateRequireCacheForFile('knex'); 
       var knex_tenant = require('knex')(knex_tenant_config); 
       var knex_pending = cb(knex_tenant); 
       Promise.resolve(knex_pending).then(function() { 
        next(null, null); 
       }); 
       } else { 
       next(null, null); 
       } 
      }); 

      }); 
     }; 
     }); 
    }); 
} 

從runTenant代碼工作正常但它檔,不繼續執行「結束()」,因爲自許「runTenant(最新)」 ISN」不要解決。

好像它不明顯,我對承諾感到恐怖。仍在努力讓我的頭在他們周圍。

非常感謝任何幫助/方向!

+0

控制檯中的任何錯誤? – JordanHendrix

回答

1

你不應該使用Promise構造都在這裏(基本上,其他任何地方都沒有),即使你讓它工作,它也會是antipattern。您從未解決過這個承諾 - 請注意resolve argumentPromise構造函數的回調函數與Promise.resolve函數是非常不同的函數。

如果你有一個功能強大的承諾庫,如藍鳥,你不應該使用async庫。

就好像它不明顯,我對承諾感到恐怖。

也許你會想看看我的rules of thumb寫作承諾函數。

這是你的功能應該是什麼樣子:

function runTenant(cb) { 
    //global var 
    if (!Tenant) { 
    loadCoreModels(); 
    Tenant = bookshelf.core.bs.model('Tenant'); 
    } 
    return new Tenant().fetchAll().then(function(tenants) { 
    // if (tenants.models.length == 0) { 
    // return; 
    // } else 
    // In case there are no models, the loop iterates zero times, which makes no difference 
    return Promise.each(tenants.models, function(tenant) { 
     var account = tenant.attributes; 
     return db_tenant.config(account).then(function(knex_tenant_config) { 
     if (knex_tenant_config) { 
      db_tenant.invalidateRequireCacheForFile('knex'); 
      var knex_tenant = require('knex')(knex_tenant_config); 
      return cb(knex_tenant); // can return a promise 
     } 
     }); 
    }); 
    }); 
} 
+0

謝謝@Bergi,完美的工作。我會仔細閱讀你的經驗規則,因爲我希望更清楚地理解......至於到底發生了什麼。我的印象是,第一個調用runTenant的代碼,因爲它在Resolve方法中,所有返回給它的promise都會得到解決,我注意到您的建議(完美工作)的主要原因是您已經解決了所有承諾回報。本上面,還建議這個。謝謝你們倆! – sol

+0

啊,是的,忘了包含一個關於你與'決心'混淆的評論。隨意評論你不明白的每個部分,我會澄清這些。 – Bergi

+0

我甚至不確定你是否需要'Promise.resolve(db_tenant.config(account))'''config(...)'返回什麼? – Bergi

0

您需要返回所有嵌套的promise。我不能運行這個代碼,所以這不是一個解決方案。但希望它能幫助你理解缺失的東西。

function runTenant(cb) { 
    //global var 
    if (!Tenant) { 
     loadCoreModels(); 
     Tenant = bookshelf.core.bs.model('Tenant'); 
    } 

    return new Tenant().fetchAll() //added return 
     .then(function (tenants) { 

      if (tenants.models.length == 0) { 
       return; 
      } else { 
       var promises = []; //got to collect the promises 
       tenants.models.each(function (tenant, next) { 

        var account = tenant.attributes; 
        var promise = Promise.resolve(db_tenant.config(account)).then(function (knex_tenant_config) { 
         if (knex_tenant_config) { 
          db_tenant.invalidateRequireCacheForFile('knex'); 
          var knex_tenant = require('knex')(knex_tenant_config); 
          var knex_pending = cb(knex_tenant); 
          return knex_pending; //return value that you want the whole chain to resolve to 
         } 
        }); 
        promises.push(promise); //add promise to collection 
       }); 
       return Promise.all(promises); //make promise from all promises 
      } 
     }); 
} 
+0

另外,它看起來像你正在使用內置的承諾。我強烈建議你改用[Bluebird](http://bluebirdjs.com/)。它內置了像Promise.each()這樣的方法,可以使這更簡單。它也有一個有用的警告系統,可能會警告你這裏的一些錯誤。 – Ben

0

您的承諾在runTenant函數永遠不會解決。你必須調用resolvereject功能來解決承諾:

function runTenant() { 
    return new Promise(function(resolve, reject) { 
    // somewhere in your code 
    if (err) { 
     reject(err); 
    } else { 
     resolve(); 
    } 
    }); 
}); 

,你不應該在runTenant功能通過cb,使用承諾鏈:

runTenant() 
.then(latest) 
.then(end) 
.catch(function(err) { 
    console.log(err); 
});