首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步调用Asynchronous Javascript函数

同步调用Asynchronous Javascript函数
EN

Stack Overflow用户
提问于 2012-02-03 08:03:01
回答 10查看 337.3K关注 0票数 266

首先,这是一个非常具体的案例,故意以错误的方式将异步调用改造成一个非常同步的代码库,该代码库有数千行长,时间目前无法进行更改以“正确地执行”。它伤害了我生命中的每一根纤维,但现实和理想往往并不协调。我知道这很糟糕。

好的,我该怎么做才能让我:

代码语言:javascript
复制
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中是可能的。

EN

回答 10

Stack Overflow用户

发布于 2019-04-04 05:30:33

您可以强制NodeJS中的异步JavaScript与sync-rpc同步。

它肯定会冻结你的用户界面,所以当谈到是否有可能走你需要走的捷径时,我仍然是一个反对者。即使NodeJS有时允许你阻止它,在JavaScript中也不可能挂起唯一的线程。没有回调,事件,任何异步的东西都可以处理,直到你的承诺解决。因此,除非读者遇到像OP这样不可避免的情况(或者,在我的例子中,正在编写一个没有回调、事件等的美化shell脚本),否则请不要这样做!

但你可以这样做:

./calling-file.js

代码语言:javascript
复制
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

代码语言:javascript
复制
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的结果

  1. 这在浏览器中无效。
  2. 函数的参数必须是可序列化的。您的参数将传入和传出JSON.stringify,因此函数和不可枚举属性(如原型链)将丢失。
票数 7
EN

Stack Overflow用户

发布于 2013-06-11 04:27:36

http://taskjs.org/上有一个很好的解决方法

它使用的是javascript新的生成器。所以它目前还没有被大多数浏览器实现。我在firefox中测试了它,对我来说,它是包装异步函数的好方法。

以下是来自项目GitHub的示例代码

代码语言:javascript
复制
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;
}
票数 6
EN

Stack Overflow用户

发布于 2020-04-13 22:44:13

你想要的现在实际上是可能的了。如果您可以在服务工作者中运行异步代码,并在web工作者中运行同步代码,则可以让web工作者向服务工作者发送同步XHR,并且当服务工作者执行异步操作时,web工作者的线程将等待。这不是一个很好的方法,但它可以工作。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9121902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档