2017-08-09 120 views
0

我想知道如何處理參數嵌套承諾。解決嵌套承諾

我有這樣的代碼:

'use strict'; 

function fetchData(tableName) { 
    new Promise((resolve, reject) => { 
    if (tableName === 'tableName2') { 
     setTimeout(reject, 200, tableName); 
    } else { 
     setTimeout(resolve, 200, tableName); 
    } 
    }); 
} 

function notifyUser(data) { 
    console.log(data); // get only undefined 3 times 
    new Promise((resolve) => { 
    setTimeout(resolve, 200, data); 
    }); 
} 

let cont = { fail:() => '', success:() => console.log }; 
function verifyAndNotify(context) { 
    let actions = []; 
    ['tableName1','tableName2','tableName3'].map(tableName => { 
    actions.push(notifyUser(fetchData(tableName))); // how to deal with this??? 
    }); 

    Promise.all(actions) 
    .then(success => { 
     console.log(`All is ok ${success}`); 
    }).catch(error => { 
     console.log(`error with: ${error}`); 
     errors.push(error); 
    }); 

    if (errors.lenght > 0) { 
    return context.fail(`Errors: ${errors}`); 
    } else { 
    return context.success(`Success`); 
    } 
} 

verifyAndNotify(cont); 

的問題是我需要給它的方法之前解決帕拉姆。我可能在JS上混合了一些我非常糟糕的東西。

我想用每個tableName通知用戶,如果「表」操作失敗(提取數據或通知),我想提出錯誤。

編輯1:意見和答案後

第一工作版本:

'use strict'; 

function fetchData(tableName) { 
    return new Promise((resolve, reject) => { 
    if (tableName === 'tableName2') { 
     setTimeout(reject, 200, tableName); 
    } else { 
     setTimeout(resolve, 200, tableName); 
    } 
    }); 
} 

function notifyUser(data) { 
    console.log(data); 
    return new Promise((resolve) => { 
    setTimeout(resolve, 200, data); 
    }); 
} 

const cont = { fail: (msg) => console.log('' + msg), done: (msg) => console.log('' + msg) }; 
function verifyAndNotify(context) { 
    const errors = []; 
    const actions = ['tableName1', 'tableName2', 'tableName3'].map(tableName => 
    fetchData(tableName).then(notifyUser).catch(error => {errors.push(error);})); 

    Promise.all(actions) 
    .then(success => { 
     if (errors.length) throw errors; 
     else { 
     context.done(`Success ${success}`); 
     } 
    }).catch(errors => { 
     context.fail(`Errors: ${errors}`); 
    }); 
} 

verifyAndNotify(cont); 
+3

你的函數應返回** **承諾,但你剛纔創建的承諾,因此,在'actions'你有三個不確定的,而不是承諾 – Grundy

+1

[如何返回從一個異步調用的響應?](/ questions/14220321/how-do-i-return-the-an-an-asynchronous-call)'verifyAndNotify()'不能返回除Promise之外的任何內容。而且'errors'不僅是空的(在你檢查它的長度的時候),它甚至不會在你的代碼中定義。 – Thomas

+1

爲什麼你使用異常來傳播'tableName ==='tableName2'?這真的是一個錯誤?接下來,Promise.all()將被拒絕並在第一次拒絕Promise時立即中止執行。你的catch()只會記錄發生的第一個錯誤;並將其推入「錯誤」。 – Thomas

回答

2

正如@Grundy說,第一個問題是,你的函數需要返回的承諾(return new Promise ...)。

至於你的行爲不勝枚舉,你可能會尋找到你的陣列映射到承諾的數組:

const actions = ['tableName1', 'tableName2', 'tableName3'].map(tableName => 
    fetchData(tableName).then(notifyUser)); 

而且,你似乎想的是有一個錯誤的每個承諾的列表,在這種情況下,您需要爲每個操作承諾添加catch,因爲Promise.all只要一個操作被拒絕就會拒絕。例如:

const errors = []; 
const actions = ['tableName1', 'tableName2', 'tableName3'].map(tableName => 
    fetchData(tableName).then(notifyUser).catch(errors.push)); 
Promise.all(actions) 
    .then(success => { 
     if (errors.length) throw errors; 
     else { 
      console.log(`All is ok ${success}`); 
      context.done(`Success`); 
     } 
    }).catch(errors => { 
     context.fail(`Errors: ${errors}`); 
    }); 
+0

非常感謝。我錯誤推送錯誤'TypeError:Array.prototype.push調用null或undefined',所以我改變了一點,併發布編輯版本的問題。 – Mio

+0

'.catch(errors.push.bind(errors))'應該這樣做。 –