2016-08-03 53 views
0

在ECMA-2015應用內(具體:陣營母語)使用ReduxRedux-Saga我們有這樣的代碼不斷龐大的使用量(工作正常,這裏是不是真正的問題):ECMA 2015:如何在回調例程中使用帶有「yield」的異步函數?

const stats = yield call([dataStorage, dataStorage.loadPrefetchingStats], languageId); 

yield put({type: ACTIONS.R_SYNCHRONIZE_STATE_PROGRESS, payload: {max: statsUnfetched, value: statsFetched}}); 

try { 
    yield importRecord(languageId, record, dataStorage) 
} 
catch(err) { 
    console.log("ERROR: ", err) 
    yield put({type: ACTIONS.R_SYNCHRONIZE_STATE_ERROR, payload: err}); 
    return false; 
} 

短問題在這裏:是否有 - 但是 - 在回調函數中結合異步函數和yield-constructs的任何可能性?

較長的問題:

要與我們使用這個夢幻般的圖書館react-native-sqlite-storage用戶設備上的本地SQLite數據庫工作。

要在事務內封裝多個SQL語句,回調是必要的這樣的:

 this.db.transaction((tx) => { 

      var sql = `UPDATE product SET prefetched=?, error_prefetching=0 WHERE id=?`; 

      return tx.executeSql(sql, [ 
       product.prefetched, 
       product.id 
      ], (tx, results) => { 
      }, (a, b) => { 
       console.log('ERROR', a,b); 
      }) ; 

     }); 

衆所周知和最佳實踐,以加快對很多很多的INSERT或UPDATE sqlite的時候被封裝所有這些語句在一個大的單一交易中。

但是由於我們正在使用Reduce和許多「yield」語句在業務邏輯和UI-Updates之間進行通信,現在我們遇到了一個問題。

有人在這裏有一個想法嗎?

+0

*「但不幸的是,它不能用於回調函數。」*這是不正確的。 'yield'只能用於發電機。所以如果回調函數是一個生成器,你可以使用它。看來你的問題是如何將使用回調的「傳統」異步函數與redux-saga結合起來。 –

+0

我在想Felix Kling說的同樣的東西。 AFAIK,產量用於發電機功能。你也可以嘗試異步/等待 –

+0

我認爲你可以創建REDX-SAIG的頻道,並且在你的回調中,不管它們的嵌套程度如何,你都可以將消息放入這個頻道(或者不同的頻道,因爲沒有匹配功能來自頻道)。然後在你的傳奇故事中,你可以從這個頻道收到信息,就像你採取重做行動一樣。傳統回調方法中也不允許「等待」 –

回答

0

無法處理生成器中的回調。更好的方法是Promisify你的回調,然後你可以使用yields來處理承諾。

考慮的功能,看起來像這樣:

function doSomething(data,callback) { 
    ... 
    ... 
    callback(); 
} 

如果你promisify它:

function promisedDoSomething(data) { 
    return new Promise((resolve) => { 
     doSomething(data, resolve); 
    } 
} 

現在你可以在發電機使用promisified功能,只是使用它與yield

var response = yield promisifiedDoSomething(data);