如何使用异步方法以同步方法 [英] How to use asynchronous method in a synchronous method

查看:207
本文介绍了如何使用异步方法以同步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发的网页技术的游戏,保存在localStorage的数据。在localStorage的工作原理synchronous.To设置,并从localStorage来值

//设置的localStorage值

  localStorage.setItem('键',值);

//从localStorage的值

  VAR localValue = localStorage.getItem('钥匙');

有在localStorage的5MB的限制。比赛后,一定程度上,localStorage的完全充满。我需要存储大面积的客户端。

我的第一个问题是,什么是解决这个问题的最好方法?

要解决以上问题,我觉得 LargeLocalStorage 。它是为异步工作。

//在LargeLocalStorage设置的值

  storage.setContents('docKey'的内容...),那么(函数(){警报('文档中创建/更新');});

//从LargeLocalStorage值

  storage.getContents('myDoc'),那么(功能(内容){//内容是针对特定键值});

有没有什么办法,因为我所有的code是根据同步localStorage的,使这些方法同步。这将需要大量的时间,根据异步LargeLocalStorage改变整个逻辑

我现在尽量覆盖的localStorage作为的setItem和方法的getItem:

  localStorage的.__原__。的getItem =功能(键){VAR returnVal;storage.getContents(键)。然后(函数(内容){
        returnVal =内容;    });
返回returnVal; //则返回undefined
}

上面覆盖方法,由于异步行为返回未定义的值。

请帮我用上述方法得到的价值是同步的。

先谢谢了。


解决方案

  

有什么办法,使这些方法同步


没有。异步方法是异步的,因为他们是很好的,异步的。你不能让那会发生什么明天(或100ms的从现在开始)的东西,而不是现在发生。

您真正想要的是写异步code以这样一种方式,它那种看起来像同步code的一种方式。这将是这两个更具可读性,并且在你的情况,将使使您的code更容易。

我们希望以某种方式能够写

  A()。然后(B)

  A();
B();

和有它指的是同一件事:等待到如果一个变量或结果参与执行B.之前完成,那么我们希望能够写

  A()。然后(功能(一){返回的B(a + 1);})

  VAR A = A();
的B(a + 1);

异步功能

原来有办法做到这一点:异步功能即可。此功能是没有在所有的环境可用的手段,但它是很容易找到的方式来访问它。要使用异步功能,我把关键字异步函数,然后使用特殊关键字<前code>的await 。所以,上面的code就像变成:

 异步函数foo(){
  VAR一个=等待A();
  等待的B(a + 1);
}

要得到这个工作,通天 transpile您code,选择启用异步功能的选项。巴贝尔将会把你的code到ES5,那种的JavaScript的浏览器都知道如何跨preT。

以上code实际上将返回一个承诺,你可以挂一个然后从,或在另一异步函数中使用:

 异步函数bar(){
  等待美孚();
}

在您的具体情况:

 异步函数write(内容){
  等待storage.setContents('docKey',内容);
  警报('文档中创建/更新');
}

发电机

有就是你可能想知道的另一种方法。它采用发电机,这是一种特殊类型的ES6函数返回一个值,但保持自己的状态,并且可以再次调用,并在两者之间做的东西后返回多个值。发电机是这样写的,用 * 函数名后:

 功能*富(){
  产量1;
  产量2;
}

此函数被调用以特殊的方式。首先,你怎么称呼它为富()来创建一个名为的迭代器的东西,然后你使用接下来迭代的方法来获取下一个值。 (也有其他的方法来检索值,我们不会去到这里的顺序。)

这些发电机可以用来写的那种,你想异步但是,看起来同步code,如下:

 功能*富(){
  VAR一个=产量A();
  产率的B(a + 1);
}

在code看起来颇为相似异步功能,但收益替换的await

但在这种情况下,与上述异步功能,我们需要某人或某事要问的第一个值,然后等待通过产量返回的承诺来解决,然后问第二个值,依此类推。在code不这样做不长,但它是一个有点复杂。有许多库和工具这恰恰如此。例如,一个公知的一个被称为的。随着,你可以写code这行为相同异步函数我在前面显示如下:

 无功富= co.wrap(功能*富(){
  VAR一个=产量A();
  产率的B(a + 1);
});

原因之一采取这种做法是将发电机在ES6标准和超过异步功能,这被认为是ES7广泛使用。

I developed a game in web technology that store the data in LocalStorage. The LocalStorage works as synchronous.To set and get the values from localstorage as

// set the value in localstorage

localStorage.setItem('Key', "value");

// get the value from localstorage

var localValue = localStorage.getItem('Key');

There is 5MB limit in localstorage. After play the some level, localstorage filled completely. I need a large area for storage at client side.

My first question is that "What is the best way to solve this problem?"

To solve above problem,I find the LargeLocalStorage.It is worked as asynchronous.

// set the value in LargeLocalStorage

storage.setContents('docKey', "the contents...").then(function() {alert('doc created/updated');});

// get the value from LargeLocalStorage

storage.getContents('myDoc').then(function(content){//content is value for particular key});

Is there is any way that make these method synchronous because my all code is according to the synchronous localstorage. It will take a lot of time to change the whole logic according to the asynchronous LargeLocalStorage.

I am currently try to override the setItem and getItem method of localstorage as :

localStorage.__proto__.getItem = function(key) {

var returnVal;

storage.getContents(key).then(function(content) {
        returnVal = content;

    });
return returnVal;//it returns undefined
}

Above override method returns undefined value due to asynchronous behaviour.

Please help me to get value synchronous using above methods.

Thanks in advance.

解决方案

Is there is any way that make these method synchronous

No. Asynchronous methods are asynchronous because they are well, asynchronous. You cannot make something that is going to happen tomorrow (or 100ms from now) instead happen now.

What you really want is a way to write asynchronous code in such a way that it sort of looks like synchronous code. That will be both more readable, and in your case, will make adapting your code easier.

We want to somehow be able to write

A() . then(B);

as

A();
B();

and have it mean the same thing: to wait for A to finish before executing B. If a variable or result is involved, then we want to be able to write

A() . then(function(a) { return B(a+1); })

as

var a = A();
B(a+1);

Async functions

It turns out there is a way to do this: async functions. This feature is by no means available in all environments, but it's easy enough to find ways to access it. To use an async function, I put the keyword async in front of the function, then use the special keyword await. So the code above becomes just:

async function foo() {
  var a = await A();
  await B(a+1);
}

To get this to work, transpile your code with Babel, selecting the options for enabling async functions. Babel will translate your code into ES5, the kind of JavaScript all browsers know how to interpret.

The above code will actually return a promise that you can either hang a then from, or use in another async function:

async function bar() {
  await foo();
}

In your specific case:

async function write(contents) {
  await storage.setContents('docKey', contents);
  alert('doc created/updated');
}

Generators

There is another approach you might like to know about. It uses "generators", which are a special type of function in ES6 which "return" a value, but maintain their state, and can be called again and return more values after doing stuff in between. Generators are written like this, with an * after the function name:

function* foo() {
  yield 1;
  yield 2;
}

This function is called in a special way. First, you call it as foo() to make a thing called an iterator, and then you use the next method of the iterator to get the next value. (There are also other ways to retrieve the sequence of values, which we won't go into here.)

These generators can be used to write the kind of "asynchronous-but-looks-synchronous" code you want, as follows:

function* foo() {
  var a = yield A();
  yield B(a+1);
}

The code looks quite similar to the async function, but with yield replacing await.

But in this case, unlike the async functions described above, we need someone or something to ask for the first value, then wait for the promise returned by yield to resolve, then ask for the second value, and so on. The code do do so is not long, but is a bit complex. There are many libraries and utilities which do exactly that. For instance, a well-known one is called co. With co, you can write code which behaves identically to the async function I showed earlier as follows:

var foo = co.wrap(function* foo() {
  var a = yield A();
  yield B(a+1);
});

One reason for adopting this approach would be that generators are standard in ES6 and more widely available than async functions, which are being considered for ES7.

这篇关于如何使用异步方法以同步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆