2017-08-10 100 views
0

簡短的問題:爲什麼在Javascript中沒有Promise.chain(相當於Promise.all)?我的實施是否?在Javascript中實現Promise.chain([...])?

我的「編解碼器」乖錯:

  1. 從XML文件
  2. 創建的所有節點讀取曲線(對創作方法返回一個承諾)
  3. 等待所有節點創作完成
  4. 創建節點之間的所有邊界

問題:數據庫的順序調用f或者節點創建(步驟2)在執行時混淆起來。

解決方案:在方法執行之前,我必須以正確的順序鏈接數據庫調用。

/** 
* chains a list of functions (that return promises) and executes them in the right order 
* [function() {return Promise.resolve();}, function() {return Promise.resolve();}] 
* 
* @param funcs is an array of functions returning promises 
* @returns {Promise} 
*/ 
function chain_promises(funcs) { 
    if (funcs.length < 1) { 
     return Promise.resolve(); 
    } 
    var i = 0; 
    return chain_executor(funcs, i); 
} 

/** 
* Recursive help method for chain_promises 
* 1) executes a function that returns a promise (no params allowed) 
* 2) chains itself to the success resolve of the promise 
* 
* @param funcs is an array of functions returning promises 
* @param i is the current working index 
*/ 
function chain_executor(funcs, i) { 
    var promise = funcs[i](); 
    return promise.then(function(){ 
     console.log(i); 
     if (funcs.length > i+1) { 
      return chain_executor(funcs, i+1); 
     } else { 
      return Promise.resolve(); 
     } 
    }) 
} 
+1

這打破了(我認爲)時結束傳遞一個空數組。 – Soronbe

+0

你是對的!在這裏包括一張支票。謝謝 – Danipol

+1

[ES6 Promise - 類似於async.each的東西]的可能重複(https://stackoverflow.com/questions/32028552/es6-promises-something-like-async-each) – jib

回答

1

使用陣列#減少你可以創建這個功能

const chain_promises = arrayOfFn => arrayOfFn.reduce((promise, fn) => 
    promise.then(results => 
     fn().then(result => 
      results.concat(result) 
     ) 
    ), Promise.resolve([]) 
); 

,或者如果你進入單行

const chain_promises = arrayOfFn => arrayOfFn.reduce((promise, fn) => promise.then(results => fn().then(result => results.concat(result))), Promise.resolve([])); 

這些額外的好處是已解決的價值es都可以在.then

例如

const chain_promises = arrayOfFn => arrayOfFn.reduce((promise, fn) => 
 
    promise.then(results => 
 
     fn().then(result => 
 
      results.concat(result) 
 
     ) 
 
    ), Promise.resolve([]) 
 
); 
 

 
const wait_promise = (time, result) => new Promise(resolve => setTimeout(resolve, time, result)); 
 
var funcs = [ 
 
    () => wait_promise(300, 'p1').then(value => ({value, date: new Date()})), 
 
    () => wait_promise(400, 'p2').then(value => ({value, date: new Date()})), 
 
    () => wait_promise(100, 'p3').then(value => ({value, date: new Date()})) 
 
]; 
 
const start = new Date(); 
 
chain_promises(funcs) 
 
.then(results => 
 
    results.reduce((a, b) => { 
 
     console.log(b.value, b.date - a); 
 
     return b.date; 
 
    }, start) 
 
);

而且,傳遞一個空數組到這個功能不會打破 - 你會空數組作爲解析值

0

入住此解決方案:

/** 
* Recursive help method for chain_promises 
* 1) executes a function that returns a promise (no params allowed) 
* 2) chains itself to the success resolve of the promise 
* 
* @param funcs is an array of functions returning promises 
* @param i is the current working index 
*/ 



function chain_promises(funcs, i) { 
    var promise = funcs[i](); 
    promise.then(function(data){ 
     console.log('function: ' + i); 
     console.log(data); 

     if (funcs.length > i+1) { 
      chain_promises(funcs, i+1); 
     } 
    }).catch(function (error) { 
     console.log(error); 
    }); 
} 

var funcs = [ 
    function() { 
    return new Promise(function(resolve, reject) { 
     console.log('wait 3 seconds to execute ...'); 
     setTimeout(function() {resolve(Date.now()); }, 3000); 
    }); 
    }, 
    function() { 
    return new Promise(function(resolve, reject) { 
     console.log('wait 5 seconds to execute ...'); 
     setTimeout(function() {resolve(Date.now()); }, 7000); 
    }); 
    }, 
    function() { 
    return new Promise(function(resolve, reject) { 
     console.log('wait 2 seconds to execute ...'); 
     setTimeout(function() {resolve(Date.now()); }, 2000); 
    }); 
    } 

]; 

if (funcs.length > 0) chain_promises(funcs, 0); 
+0

jsbin上的演示:http:// jsbin.com/ponesan/edit?js,console –