2016-05-15 41 views
-2

我想獲取數據並準備好將其作爲另一個函數用作javaScript對象。問題是數據在程序完成後被提取。這裏是該項目的鏈接:https://github.com/bigbassroller/isomorphic-js/blob/master/src/components/pages/Home/HomeController.js。在此處查看代碼:與JavaScript同步獲取數據異步數據

import "babel-polyfill"; 
import Controller from '../../../lib/controller'; 
import nunjucks from 'nunjucks'; 
import fetch from "isomorphic-fetch"; 
import promise from "es6-promise"; 


function onClick(e) { 
    console.log(e.currentTarget); 
} 

function getData(context) { 
let data = { 
    "name": "Leanne Graham" 
} 
return data; 
} 

function fetchData(context) { 
    return fetch("http://jsonplaceholder.typicode.com/users/1").then(function(response) { 
     let data = response.json().body; 
     return data; 
    }); 
} 


export default class HomeController extends Controller { 


    index(application, request, reply, callback) { 
    this.context.cookie.set('random', '_' + (Math.floor(Math.random() * 1000) + 1), { path: '/' }); 
    this.context.data = { random: Math.floor(Math.random() * 1000) + 1 }; 
    callback(null); 
    } 

    toString(callback) { 

    // Works 
    let context = getData(this.context); 
    // Doesn't work 
    // let context = fetchData(this.context); 

    context.data = this.context.data; 

    nunjucks.render('components/pages/Home/home.html', context, (err, html) => { 
     if (err) { 
     return callback(err, null); 
     } 

     callback(null, html); 
    }); 
    } 

    attach(el) { 
    console.log(this.context.data.random); 
    this.clickHandler = el.addEventListener('click', onClick, false); 
    } 

    detach(el) { 
    el.removeEventListener('click', onClick, false); 
    } 

} 

是否有可能在頁面呈現之前獲取數據?我試圖儘可能保持香草,因爲我正在儘可能地學習。我一直試圖解決這個問題,因此我一直在尋求幫助,並幫助其他有相同問題的人。 我的問題類似於這個問題,https://github.com/reactjs/redux/issues/99,但我沒有嘗試使用redux,而寧可使用promises。

+3

在進行異步調用時,請不要考慮同步函數調用和執行。相反,開始考慮回調和事件。歡迎來到異步世界。 –

+0

您能否提供一些關於代碼執行方式的更多上下文。你提到「程序」,但這有點含糊。它是Node中的程序嗎?它只是在HTML頁面中運行JavaScript嗎?你正在寫一個函數嗎?你在使用其他框架嗎? –

+0

抱歉是含糊不清。這裏是我嘗試使用該功能的真實生活項目的鏈接:https://github.com/bigbassroller/isomorphic-js/blob/master/src/components/pages/Home/HomeController.js getData需要返回tostring(回調)函數內的控制器要使用的對象。 謝謝大家的幫助。我意識到我處於我的頭上,但這是我目前感興趣的事情,我真的想解決並理解這個問題。 – mchavezi

回答

0

使用異步呼叫時,無法保證呼叫何時返回(因此是異步)。這意味着如果你想在數據返回之後完成某件事情,那麼做的地方就在「then」子句中。

你能否在這裏解釋一下你的用例?

+0

感謝您的提示,我會亂搞這個想法。該用例適用於基於「建立同構Javascript Web應用程序」一書的同構Web應用程序。數據需要在渲染時序列化,以便在服務器和客戶端上使用。 – mchavezi

0

這是不可能的。你需要改變你的程序設計才能使用它。下面是一個簡單的例子:

假設你有一些功能foo()返回一個string

function foo() { 
    x = fetchSync(); 
    return x; 
} 

現在,假設你沒有fetchSync()和你不得不做的工作異步計算string回來。您的功能不再可能在達到功能結束之前準備好返回string

那麼你如何解決它?你重新設計foo()函數也是異步的。

function foo(callback) { 
    // kick off fetch 
    fetch(function(response) { 
    // call callback() with the 
    // the results when fetch is done 
    callback(response.json()) 
    }); 
} 

同例如使用承諾:

運行JavaScript的支持異步設計
function foo() { 
    return fetch().then(function(response) { 
    return response.json(); 
    }); 
} 

一般來說大多數環境。例如,在Node中,如果存在仍可被調用的回調註冊,則JavaScript程序將無法完成運行。

+0

賽義德感謝您詳細的解釋:)我修改了我與你的代碼工作, \t \t功能fetchData(上下文){ \t \t返回讀取(「http://jsonplaceholder.typicode.com/users/1」) 。然後(功能(響應){。 \t \t令數據= response.json()主體; \t \t返回數據; \t \t}); \t \t} 該應用不會崩潰,但它顯示數據在nunjucks模板中不可用。如果數據被傳入,最好的方法是什麼?當我console.log數據,它說未定義。 – mchavezi

+0

我正在運行,但這裏有一個很快的事情,我可以幫忙:http://jsbin.com/woyojunihu/edit?html,js,output –