首先,这是一个非常具体的案例,故意以错误的方式将异步调用改造成一个非常同步的代码库,该代码库有数千行长,时间目前无法进行更改以“正确地执行”。它伤害了我生命中的每一根纤维,但现实和理想往往并不协调。我知道这很糟糕。
好的,我该怎么做才能让我:
function doSomething() {
var data;
function callBack(d) {
data = d;
}
myAsynchronousCall(param1, callBack);
// block here and return data when the callback is finished
return data;
}示例(或缺少示例)都使用库和/或编译器,这两个都不适用于此解决方案。我需要一个具体的例子来说明如何在不冻结UI的情况下使其阻塞(例如,在调用回调之前不离开doSomething函数)。如果这样的事情在JS中是可能的。
发布于 2019-04-04 05:30:33
您可以强制NodeJS中的异步JavaScript与sync-rpc同步。
它肯定会冻结你的用户界面,所以当谈到是否有可能走你需要走的捷径时,我仍然是一个反对者。即使NodeJS有时允许你阻止它,在JavaScript中也不可能挂起唯一的线程。没有回调,事件,任何异步的东西都可以处理,直到你的承诺解决。因此,除非读者遇到像OP这样不可避免的情况(或者,在我的例子中,正在编写一个没有回调、事件等的美化shell脚本),否则请不要这样做!
但你可以这样做:
./calling-file.js
var createClient = require('sync-rpc');
var mySynchronousCall = createClient(require.resolve('./my-asynchronous-call'), 'init data');
var param1 = 'test data'
var data = mySynchronousCall(param1);
console.log(data); // prints: received "test data" after "init data"./my-asynchronous-call.js
function init(initData) {
return function(param1) {
// Return a promise here and the resulting rpc client will be synchronous
return Promise.resolve('received "' + param1 + '" after "' + initData + '"');
};
}
module.exports = init;限制:
这都是由于滥用require('child_process').spawnSync来实现sync-rpc的结果
JSON.stringify,因此函数和不可枚举属性(如原型链)将丢失。发布于 2013-06-11 04:27:36
在http://taskjs.org/上有一个很好的解决方法
它使用的是javascript新的生成器。所以它目前还没有被大多数浏览器实现。我在firefox中测试了它,对我来说,它是包装异步函数的好方法。
以下是来自项目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;
}发布于 2020-04-13 22:44:13
你想要的现在实际上是可能的了。如果您可以在服务工作者中运行异步代码,并在web工作者中运行同步代码,则可以让web工作者向服务工作者发送同步XHR,并且当服务工作者执行异步操作时,web工作者的线程将等待。这不是一个很好的方法,但它可以工作。
https://stackoverflow.com/questions/9121902
复制相似问题