同步调用asynchronousJavaScript函数
首先,这是一个非常特殊的情况,它是通过错误的方式将asynchronous调用改造成一个非常同步的代码库,这个代码库长达数千行,而且时间目前还没有能力做出改变对的。” 它伤害了我存在的每一根纤维,但是现实和理想往往不会啮合。 我知道这很糟糕。
好吧,那边,我该怎么做才能做到这一点:
function doSomething() { var data; function callBack(d) { data = d; } myAsynchronousCall(param1, callBack); // block here and return data when the callback is finished return data; }
这些例子(或缺乏)都使用库和/或编译器,这两种方法都不适用于此解决scheme。 我需要一个具体的例子来说明如何使它不被冻结(例如不要离开doSomething函数,直到调用callback函数)。 如果这样的事情在JS中是可能的。
“不要告诉我应该怎么做”,正确的方式“或任何”
好。 但是你应该以正确的方式去做,或者其他任何事情
“我需要一个具体的例子来说明如何使它不被冻结,如果这样的事情在JS中是可能的。
不,不可能在不阻止用户界面的情况下阻止运行的JavaScript。
鉴于缺乏信息,很难提供一个解决scheme,但有一个select可能是让调用函数做一些轮询来检查全局variables,然后将callback集data
传递给全局。
function doSomething() { // callback sets the received data to a global var function callBack(d) { window.data = d; } // start the async myAsynchronousCall(param1, callBack); } // start the function doSomething(); // make sure the global is clear window.data = null // start polling at an interval until the data is found at the global var intvl = setInterval(function() { if (window.data) { clearInterval(intvl); console.log(data); } }, 100);
所有这一切都假定你可以修改doSomething()
。 我不知道是否在卡片中。
如果可以修改,那么我不知道为什么你不会只是通过callbackdoSomething()
从另一个callback中调用,但我最好停止之前,我陷入困境。 ;)
哦,到底是什么。 你举了一个例子,表明它可以正确完成,所以我要展示解决scheme…
function doSomething( func ) { function callBack(d) { func( d ); } myAsynchronousCall(param1, callBack); } doSomething(function(data) { console.log(data); });
因为你的例子包含一个传递给asynchronous调用的callback函数,所以正确的方法是传递一个函数doSomething()
以从callback函数中调用。
当然,如果这是唯一的callback,你只是直接传递func
…
myAsynchronousCall(param1, func);
看看JQuery的承诺:
http://api.jquery.com/promise/
http://api.jquery.com/jQuery.when/
http://api.jquery.com/deferred.promise/
重构代码:
var dfd = new jQuery.Deferred(); 函数callBack(data){ dfd.notify(数据); } / /做asynchronous调用。 myAsynchronousCall(param1,callBack); 函数doSomething(data){ //用数据做东西... } $。当(DFD)。然后(DoSomething的);
asynchronous函数是ES2017中的一个function,通过使用promise (asynchronous代码的一种特殊forms)和await
关键字使asynchronous代码看起来同步。 另请注意关键字前的关键字async
。
ES2017于2017年6月27日获得批准(即最终完成)。asynchronous等待可能已经在您的浏览器中正常工作,但是如果没有,您仍然可以使用像babel或traceur这样的javascript转换程序的function。 Chrome 55完全支持asynchronousfunction。 所以如果你有一个更新的浏览器,你可以试试下面的代码。
一个名为doAsync
async await函数doAsync
:
function timeoutPromise (time) { return new Promise(function (resolve) { setTimeout(function () { resolve(Date.now()); }, time) }) } function doSomethingAsync () { return timeoutPromise(100); } function doSomethingElseAsync () { return timeoutPromise(150); } function doMoreAsnycStuff () { return timeoutPromise(300); } // this calls each promise returning function one after the other async function doAsync () { var response = []; // each index is a promise returning function var promiseFuncs= [doSomethingAsync, doSomethingElseAsync, doMoreAsnycStuff]; for(var i = 0; i < promiseFuncs.length; ++i) { var promiseFunc = promiseFuncs[i]; response = response.concat(await promiseFunc()); console.log(response); } // do something with response return response } doAsync().then(function (response) { console.log(response) })
在http://taskjs.org/有一个很好的解决方法;
它使用JavaScript新的生成器。 所以目前大多数浏览器都没有实现。 我testing了它在Firefox中,对我来说这是很好的方式来包装asynchronousfunction。
这是来自项目GitHub的示例代码
var { Deferred } = task; spawn(function() { out.innerHTML = "reading...\n"; try { var d = yield read("read.html"); alert(d.responseText.length); } catch (e) { e.stack.split(/\n/).forEach(function(line) { console.log(line) }); console.log(""); out.innerHTML = "error: " + e; } }); function read(url, method) { method = method || "GET"; var xhr = new XMLHttpRequest(); var deferred = new Deferred(); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status >= 400) { var e = new Error(xhr.statusText); e.status = xhr.status; deferred.reject(e); } else { deferred.resolve({ responseText: xhr.responseText }); } } }; xhr.open(method, url, true); xhr.send(); return deferred.promise; }