甜点

文章 评论 浏览 28

甜点 2025-02-13 02:57:12

我修复了它,我不确定我更改了什么,但我必须制作一个新项目,在appshell.xaml中有标签,您必须添加shell.flyoutbehavior =“ flyout”,也必须添加添加< shellContent> tag < shellContent>

i fixed it, iam not really sure what i changed but i had to make a new project and in the AppShell.xaml there is the tag and you have to add Shell.FlyoutBehavior="Flyout" and also add the <ShellContent> tag <ShellContent>

.net maui不起作用的shellcontent标签

甜点 2025-02-12 03:52:42

当Citrix退出时,此参考的注册表条目更有可能不会永久保存。与您的Citrix管理员讨论永久添加注册表条目。否则,请考虑在Citrix(VBScript或PowerShell)中运行脚本,而不是直接运行您的访问应用程序,该脚本将其添加到运行时的注册表中,然后启动您的应用程序。

It's more likely that the registry entry for this reference simply isn't getting saved permanently when Citrix exits. Talk to your Citrix admin about adding the registry entries permanently. Otherwise, rather than running your Access app directly in Citrix, consider running a script in Citrix (vbscript or Powershell) which adds the reference for this to the registry at runtime and then starts your app.

赎回Outlook VBA参考总是在Citrix中重置

甜点 2025-02-11 21:31:23

添加用户作为useffect's 依赖项数组

  useEffect(() => {
    if (!user) {
      navigate('/')
    } else {
      checkUser();
    }
  }, [user]);

Add user as a dependency to the useEffect's dependency array:

  useEffect(() => {
    if (!user) {
      navigate('/')
    } else {
      checkUser();
    }
  }, [user]);

提交后如何持续更新的表单数据?

甜点 2025-02-11 12:03:08

目前这可能是不可能的,但应通过此拉请求

This may be impossible currently, but should be solved by this pull request.

无法从Docker容器连接到Protonmail Bridge SMTP(主机)

甜点 2025-02-11 08:47:01

在运行ng -version时,我也面临着同一问题。我试图卸载并重新安装,但它不起作用。使用CLI 14,ng -version不起作用。

因此,请改用ng版本

I was also facing the same issue while running the ng --version. I tried to uninstall and reinstall but it didn't work. With cli 14, ng --version doesn't work.

So use ng version instead.

Angular-错误:您需要在继续之前指定命令。使用&#x27; - 帮助&#x27;查看可用命令

甜点 2025-02-11 06:12:27

您可以使用ID,例如:&lt; p id =“ p1”&gt;&lt;/p&gt;
或类,例如:&lt; p class =“ p1”&gt;&lt;/p&gt;
在每个元素上
或从标签内部设置样式,例如&lt; p style =“ color:black;”&gt;&lt;/p&gt;。据我所知,这些是您所希望的唯一方法。

You could use id such as: <p id="p1"></p>
or class such as: <p class="p1"></p>
on each element
or set the style from inside the tag such as <p style="color:black;"></p>. These are as far as I know the only ways you could do what you're hoping for.

在编写CSS时,您将拥有多个&lt; p&gt;所有人都需要单独颜色的标签您只是继续编写单独编写&lt; p&gt;选择器还是...?

甜点 2025-02-11 05:15:56

这是我解决相同问题的方式:

  1. 转到您的CUDA主文件夹路径及其v10.x或v11.x子文件夹。

    在我的情况下是来自目录路径:
    c:\ program Files \ nvidia gpu计算工具包\ cuda \ v11.7

    “在此处输入图像描述”

  2. 复制 nvmm 整个文件夹。

  3. 将其粘贴到您当前的Python工作目录中。

    在我的情况下,使用pycharm,它必须是 .idea __ pycache __ __ 文件夹的目录,和 venv 文件夹(照片中未显示)

  4. 再次运行您的程序/代码。它应该现在起作用,并且不会显示 错误:找不到libdevice目录$ {cuda_dir}/nvvm/libdevice

Here is how I solve the same problem:

  1. Go to your CUDA main folder path and its v10.x or v11.x sub-folder.

    In my case is from the directory path:
    C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7

    enter image description here

  2. Copy the nvmm whole folder.

  3. Paste it into your current python working directory.

    In my case using Pycharm, it must be the same directory with .idea and __pycache__ folder, and venv folder (not shown in the photo)
    enter image description here

  4. Run your program/code again. It should work now and won't show up error: Can't find libdevice directory ${CUDA_DIR}/nvvm/libdevice anymore.

我有关于错误的错误:可以找到libdevice目录$ {cuda_dir}/nvvm/libdevice in tensorflow object_detection_detection_detection api

甜点 2025-02-11 05:13:14

为了提供帮助:

  1. Google 3P授权Javascript javascript javascript库 in 我们可以检查新库具有的所有方法(它不会刷新令牌等。
  2. 此链接 GIS#cookies“ rel =“ nofollow noreferrer”>此文档说库不会控制cookie以保持状态。

解决方案

如Sam所述:“您可以以某种方式保存访问令牌,并在重新加载后加快它来加速事物。”

给定 Google的Exampe ,我们应该应该调用inittokencLient为了配置Google auth和requestAcccessToken以弹出auth:

tokenClient = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly',
          prompt: 'consent',
          callback: tokenCallback
      });
tokenClient.requestAccessToken({prompt: ''})

在您的tokencallback中,您可以保存以某种方式保存凭据,例如:

const tokenCallback(credentials) => {
    // save here the credentials using localStorage or cookies or whatever you want to.
}

最后,当您重新启动/重新加载应用程序并初始化gapi.server再次初始化时,您只需要再次获得凭据并将令牌设置为gapi,例如:

gapi.load('client', function() {
    gapi.client.init({}).then(function() {
      let credentials = // get your credentials from where you saved it
      credentials = JSON.parse(credentials); // parse it if you got it as string
      gapi.client.setToken(credentials);

      ... continue you app ...
    }).catch(function(err) {
      // do catch...
    });
});

这样做,您的应用程序将在重新加载后起作用。我知道这不是最好的解决方案,但是看到您拥有的内容和图书馆提供的内容,我认为您可以做到。

ps:令牌在1小时后到期,并且没有刷新令牌(使用隐式流),因此,您必须要求用户再次登录。

In order to help:

  1. Google 3P Authorization JavaScript Library: in this link we can check all the methods the new library has (it does not refresh token, etc..)
  2. This doc says the library won't control the cookies to keep the state anymore.

Solution

As Sam described: "you can somehow save access token and use it to speed-up things after page reload."

Given the the Google's exampe, we should call initTokenClient in order to configure the Google Auth and the requestAccessToken to popup the auth:

tokenClient = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly',
          prompt: 'consent',
          callback: tokenCallback
      });
tokenClient.requestAccessToken({prompt: ''})

In your tokenCallback you can save the credentials you get somehow, e.g.:

const tokenCallback(credentials) => {
    // save here the credentials using localStorage or cookies or whatever you want to.
}

Finally, when you restart/reload your application and you initialize the gapi.server again, you only need to get the credentials again and set token to gapi, like:

gapi.load('client', function() {
    gapi.client.init({}).then(function() {
      let credentials = // get your credentials from where you saved it
      credentials = JSON.parse(credentials); // parse it if you got it as string
      gapi.client.setToken(credentials);

      ... continue you app ...
    }).catch(function(err) {
      // do catch...
    });
});

Doing it, your application will work after the reload. I know it could not be the best solution, but seeing what you have and the library offers, I think that's you can do.

p.s.: the token expires after 1 hour and there is no refresh token (using the implicit flow) so, you will have to ask the user to sign-in again.

Google身份服务:如何保存会话

甜点 2025-02-10 22:51:36

将接口重命名为处理器Animaldog,您将看到为什么编译器对类型以及您试图使用的内容是正确的没有意义。

这是重命名:

interface Animal // FeaturedCardAdapterContract.View

interface Processor<A: Animal> { // FeaturedCardAdapterContract.SubPresenter<V>
    fun process(animal: A) // onBind
}

interface Dog: Animal // FeaturedTestAdapterContract.View
interface DogProcessor: Processor<Dog> // FeaturedTestAdapterContract.Presenter

main中,您创建了一个2 dogprocessor s的数组:

val processorImpl1 = object: DogProcessor {
    override fun process(animal: Dog) {

    }
}

val processorImpl2 = object: DogProcessor {
    override fun process(animal: Dog) {

    }
}

val array = arrayOf(processorImpl1, processorImpl2)

然后,您正在尝试循环遍历它,并让它们每个过程都有动物:

val array = arrayOf(processorImpl1, processorImpl2)
for (processor in array) {
    processor.process(object: Animal {

    })
}

这显然是无论您如何更改array的类型,都不会工作。阵列过程中的处理器特定于,而不是一般的动物。您只需给它而不是动物而不是动物来完成这项工作,或者在您的情况下:

val interfaceArray = arrayOf(featureImpl1, featureImpl2)

for (featureImpl in interfaceArray) {
    featureImpl.onBind(object : FeaturedTestAdapterContract.View {
        override fun onCreate() {
            //
        }
    })
}

请注意,可以将阵列的类型更改为Array&lt; processor&lt; out Animal&gt;&gt;&gt; - 一个数组仅生产动物的处理器。这是因为狗的生产者是动物的生产者。另请参阅: pecs 。但是,由于您想调用processonbind),因此您希望处理器 摄入,或消耗动物,而不是产生一个。因此,数组&lt; processor&lt; out Animal&gt;不是您想要的。

Rename the interfaces to Processor, Animal, and Dog, and you will see why the compiler is correct about the types and what you are trying to do doesn't make sense.

Here's the renaming:

interface Animal // FeaturedCardAdapterContract.View

interface Processor<A: Animal> { // FeaturedCardAdapterContract.SubPresenter<V>
    fun process(animal: A) // onBind
}

interface Dog: Animal // FeaturedTestAdapterContract.View
interface DogProcessor: Processor<Dog> // FeaturedTestAdapterContract.Presenter

In main, you are creating an array of 2 DogProcessors:

val processorImpl1 = object: DogProcessor {
    override fun process(animal: Dog) {

    }
}

val processorImpl2 = object: DogProcessor {
    override fun process(animal: Dog) {

    }
}

val array = arrayOf(processorImpl1, processorImpl2)

Then you are trying to loop through it and have them each process an animal:

val array = arrayOf(processorImpl1, processorImpl2)
for (processor in array) {
    processor.process(object: Animal {

    })
}

This is obviously not going to work no matter how you change the type of array. The processors in the array process dogs specifically, not animals in general. You could simply make this work by just giving it dogs instead of animals, or in your case:

val interfaceArray = arrayOf(featureImpl1, featureImpl2)

for (featureImpl in interfaceArray) {
    featureImpl.onBind(object : FeaturedTestAdapterContract.View {
        override fun onCreate() {
            //
        }
    })
}

Note that the type of the array can be changed to Array<Processor<out Animal>> - an array of processors that only produces animals. This is because a producer of dogs is a kind of producer of animals. See also: PECS. However, since you want to call process (onBind) here, you want the processor to take in, or consume an animal, not produce one. Therefore, Array<Processor<out Animal>> is not what you want.

Kotlin通用自动转换为“ out”

甜点 2025-02-10 07:36:59

尝试:

s = "key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"

x = (
    pd.Series(s)
    .str.extractall(r"key=(?P<key>.*?),\s*age=(?P<age>.*?)(?=,|\Z)")
    .reset_index(drop=True)
)
print(x)

打印:

     key age
0  IAfpK  58
1  WNVdi  64
2  jp9zt  47

Try:

s = "key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"

x = (
    pd.Series(s)
    .str.extractall(r"key=(?P<key>.*?),\s*age=(?P<age>.*?)(?=,|\Z)")
    .reset_index(drop=True)
)
print(x)

Prints:

     key age
0  IAfpK  58
1  WNVdi  64
2  jp9zt  47

转换为Pandas DF

甜点 2025-02-10 05:00:36

对我来说,scollview不起作用,因为这是由于某些原因由&lt; touchableWithAbleWithOutFeedback&gt;/touchablewithablewithablewithablewithOutfeedback&gt;标记。

For me ScrollView was not working because it was for some reasons wrapped by <TouchableWithoutFeedback></TouchableWithoutFeedback> tags.

React Native ScrollView不滚动

甜点 2025-02-10 00:52:08

添加一个textViewsetOnClickListener

xml文件

<androidx.cardview.widget.CardView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
>
  <TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Start"
    android:id="@+id/text_start_stop"
  />
  </androidx.cardview.widget.CardView>

class

private TextView tStartStop;
Boolean flag = true;

clickevent

tStartStop = findViewById(R.id.text_start_stop);
tStartStop.setOnClickListener(view -> {
  if (flag) {
    flag = false;
    tStartStop.setText("Start");
  } else {
    flag = true;
    tStartStop.setText("Stop");
  }
});

Add one TextView and setOnClickListener

XML File

<androidx.cardview.widget.CardView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
>
  <TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Start"
    android:id="@+id/text_start_stop"
  />
  </androidx.cardview.widget.CardView>

Class

private TextView tStartStop;
Boolean flag = true;

ClickEvent

tStartStop = findViewById(R.id.text_start_stop);
tStartStop.setOnClickListener(view -> {
  if (flag) {
    flag = false;
    tStartStop.setText("Start");
  } else {
    flag = true;
    tStartStop.setText("Stop");
  }
});

如何实现开始/停止“按钮”在Android中

甜点 2025-02-09 18:07:21

Fastai库不包含称为步进模型的模块。对于NLP,您使用fastai.text模块,而不是fastai.nlp。这是一个教程,说明:

https://docs.fast.fast.ai/tutorial.tutorial.text.text.html < /a>

您在哪里找到包含您要运行的两行的代码?它不是Fastai V1或V2代码。也许是从Part2课程开始,像Fastai这样的东西是从头开始重写的? https://course19.fast.fast.ai/part2 。如果是这样,您需要从那里使用笔记本。

The fastai library does not contain modules called stepper or model. For NLP you use the fastai.text modules, not fastai.nlp. Here's a tutorial explaining how:

https://docs.fast.ai/tutorial.text.html

Where did you find code containing the two lines you're trying to run? It's not fastai v1 or v2 code. Perhaps it's from the part2 course where something like fastai was rewritten from scratch? https://course19.fast.ai/part2. If so, you'll need to use the notebooks from there.

ModulenotFoundError:No模块名为&#x27; fastai.nlp&#x27;

甜点 2025-02-09 15:42:14
"[^a-zA-Z0-9\u0621-\u064Aa\u0660-\u0669\s\)\(\-\.\:\"\?_,]+"

将允许阿拉伯字符和数字,然后允许英文字符和数字,然后允许您认为您想要的特殊字符。 \ u0660- \ u0669检查阿拉伯语数字,\ u0621- \ u064a检查阿拉伯字符。让我知道这是否有效,以及我是否正确解释了您。

"[^a-zA-Z0-9\u0621-\u064Aa\u0660-\u0669\s\)\(\-\.\:\"\?_,]+"

would allow arabic characters and numbers then english characters and numbers then the special characters I think you want. \u0660-\u0669 checks for arabic numbers and \u0621-\u064A checks for arabic characters. Let me know if this works and whether or not I interpreted you correctly.

阿拉伯语和英语的正则表达

甜点 2025-02-09 14:00:22

如果您使用的是承诺,则此答案适合您。

这意味着Angularjs,jQuery(带延迟),本机 xhr“> xhr”> xhr href =“ https://en.wikipedia.org/wiki/ember.js” rel =“ noreferrer”> ember.js , backbone.js 's保存或任何 noreferrer“ .js 返回承诺的库。

您的代码应该与此相似:

function foo() {
    var data;
    // Or $.get(...).then, or request(...).then, or query(...).then
    fetch("/echo/json").then(function(response){
        data = response.json();
    });
    return data;
}

var result = foo(); // 'result' is always undefined no matter what.

Felix Kling做得很好为使用jQuery和回调的人写答案。我有一个本地XHR的答案。这个答案是用于对前端或后端上承诺的一般用法。


核心问题

在浏览器和服务器上使用node.js/io.js在服务器中的JavaScript并发模型是 asynchronous 反应性

每当您调用返回诺言的方法时,然后处理程序始终异步执行 - 也就是说, 下方的代码不是在中。然后处理程序。

这意味着,当您返回数据 处理程序尚未执行。反过来,这意味着您要返回的值尚未设置为正确的值。

这是一个简单的类比:

    function getFive(){
        var data;
        setTimeout(function(){ // Set a timer for one second in the future
           data = 5; // After a second, do this
        }, 1000);
        return data;
    }
    document.body.innerHTML = getFive(); // `undefined` here and not 5

data的值是不确定的,因为data = 5零件尚未执行。它可能会在一秒钟内执行,但是到那时,它与返回的值无关。

由于该操作尚未发生(AJAX,服务器调用,I/O和计时器),您在请求有机会告诉您的代码是什么值之前返回值。

解决此问题的一种可能解决方案是代码 ,告诉您的程序完成计算后该怎么办。承诺通过本质上是时间(时间敏感)来积极实现这一目标。

快速回顾承诺的

承诺是随时间的价值。承诺有状态。他们从没有价值的待审开始,可以安定下来:

  • 实现意味着计算成功完成。
  • 拒绝意味着计算失败。

诺言只能改变状态 之后,它将永远永远处于同一状态。您可以将附加处理程序附加到承诺提取其价值并处理错误的承诺。 然后处理程序允许 chaning> chaning> chaning 。承诺由使用返回它们。例如,更现代的AJAX替换Fetch或jQuery的$。get返回承诺。

当我们调用。如果我们回报另一个诺言,我们会得到令人惊奇的事情,但让我们握住马匹。

有了承诺,

让我们看看如何通过承诺解决上述问题。首先,让我们通过使用 Promise构造函数用于创建延迟函数:

function delay(ms){ // Takes amount of milliseconds
    // Returns a new promise
    return new Promise(function(resolve, reject){
        setTimeout(function(){ // When the time is up,
            resolve(); // change the promise to the fulfilled state
        }, ms);
    });
}

现在,在我们转换的settimeout 要使用诺言,我们可以使用然后来计算:

function delay(ms){ // Takes amount of milliseconds
  // Returns a new promise
  return new Promise(function(resolve, reject){
    setTimeout(function(){ // When the time is up,
      resolve(); // change the promise to the fulfilled state
    }, ms);
  });
}

function getFive(){
  // We're RETURNING the promise. Remember, a promise is a wrapper over our value
  return delay(100).then(function(){ // When the promise is ready,
      return 5; // return the value 5. Promises are all about return values
  })
}
// We _have_ to wrap it like this in the call site, and we can't access the plain value
getFive().then(function(five){
   document.body.innerHTML = five;
});

基本上,而不是返回 value ,我们由于并发模型而无法做,而是我们返回a wrapper ,以获取我们可以 unwrap <的值/em>带有<代码>然后。就像一个框,您可以使用然后打开。

在原始API调用中应用

此信息相同,您可以:

function foo() {
    // RETURN the promise
    return fetch("/echo/json").then(function(response){
        return response.json(); // Process it inside the `then`
    });
}

foo().then(function(response){
    // Access the value inside the `then`
})

这样也可以。我们已经了解到,我们无法从已经异步的调用中返回值,但是我们可以使用诺言并将其链接来执行处理。现在,我们知道如何从异步呼叫中返回响应。

ES2015(ES6)

ES6引入是可以在中间返回然后恢复其点的功能。例如,这通常对于序列很有用,例如:

function* foo(){ // Notice the star. This is ES6, so new browsers, Nodes.js, and io.js only
    yield 1;
    yield 2;
    while(true) yield 3;
}

是一个函数,该函数可以通过序列返回序列1,2,3,3,3,3,....可以迭代。尽管这本身很有趣,并为很多可能性打开了空间,但有一个特别的案例。

如果我们要产生的序列是一系列动作,而不是数字 - 我们可以在恢复函数之前等待动作并等待该功能。因此,我们需要一个 future 值的序列,而不是数字序列,也就是说:承诺。

这有点棘手,但非常有力的技巧让我们以同步的方式编写异步代码。有几个“跑步者”为您做到这一点。写一条是几行代码,但它超出了该答案的范围。我将在此处使用Bluebird的Promise.coroutine,但是还有其他包装器,例如co <​​/code>或q.async

var foo = coroutine(function*(){
    var data = yield fetch("/echo/json"); // Notice the yield
    // The code here only executes _after_ the request is done
    return data.json(); // 'data' is defined
});

此方法返回了一个承诺本身,我们可以从其他coroutines中消费。例如:

var main = coroutine(function*(){
   var bar = yield foo(); // Wait our earlier coroutine. It returns a promise
   // The server call is done here, and the code below executes when done
   var baz = yield fetch("/api/users/" + bar.userid); // Depends on foo's result
   console.log(baz); // Runs after both requests are done
});
main();

ES7中的ES2016(ES7)

,这是进一步标准化的。现在有几个建议,但是在所有建议中,您都可以等待承诺。这只是上述ES6提案的“糖”(较好的语法),通过添加async等待关键字。进行上面的示例:

async function foo(){
    var data = await fetch("/echo/json"); // Notice the await
    // code here only executes _after_ the request is done
    return data.json(); // 'data' is defined
}

它仍然返回承诺同样的示例:)

If you're using promises, this answer is for you.

This means AngularJS, jQuery (with deferred), native XHR's replacement (fetch), Ember.js, Backbone.js's save or any Node.js library that returns promises.

Your code should be something along the lines of this:

function foo() {
    var data;
    // Or $.get(...).then, or request(...).then, or query(...).then
    fetch("/echo/json").then(function(response){
        data = response.json();
    });
    return data;
}

var result = foo(); // 'result' is always undefined no matter what.

Felix Kling did a fine job writing an answer for people using jQuery with callbacks for Ajax. I have an answer for native XHR. This answer is for generic usage of promises either on the frontend or backend.


The core issue

The JavaScript concurrency model in the browser and on the server with Node.js/io.js is asynchronous and reactive.

Whenever you call a method that returns a promise, the then handlers are always executed asynchronously - that is, after the code below them that is not in a .then handler.

This means when you're returning data the then handler you've defined did not execute yet. This in turn means that the value you're returning has not been set to the correct value in time.

Here is a simple analogy for the issue:

    function getFive(){
        var data;
        setTimeout(function(){ // Set a timer for one second in the future
           data = 5; // After a second, do this
        }, 1000);
        return data;
    }
    document.body.innerHTML = getFive(); // `undefined` here and not 5

The value of data is undefined since the data = 5 part has not executed yet. It will likely execute in a second, but by that time it is irrelevant to the returned value.

Since the operation did not happen yet (Ajax, server call, I/O, and timer) you're returning the value before the request got the chance to tell your code what that value is.

One possible solution to this problem is to code re-actively, telling your program what to do when the calculation completed. Promises actively enable this by being temporal (time-sensitive) in nature.

Quick recap on promises

A Promise is a value over time. Promises have state. They start as pending with no value and can settle to:

  • fulfilled meaning that the computation completed successfully.
  • rejected meaning that the computation failed.

A promise can only change states once after which it will always stay at the same state forever. You can attach then handlers to promises to extract their value and handle errors. then handlers allow chaining of calls. Promises are created by using APIs that return them. For example, the more modern Ajax replacement fetch or jQuery's $.get return promises.

When we call .then on a promise and return something from it - we get a promise for the processed value. If we return another promise we'll get amazing things, but let's hold our horses.

With promises

Let's see how we can solve the above issue with promises. First, let's demonstrate our understanding of promise states from above by using the Promise constructor for creating a delay function:

function delay(ms){ // Takes amount of milliseconds
    // Returns a new promise
    return new Promise(function(resolve, reject){
        setTimeout(function(){ // When the time is up,
            resolve(); // change the promise to the fulfilled state
        }, ms);
    });
}

Now, after we converted setTimeout to use promises, we can use then to make it count:

function delay(ms){ // Takes amount of milliseconds
  // Returns a new promise
  return new Promise(function(resolve, reject){
    setTimeout(function(){ // When the time is up,
      resolve(); // change the promise to the fulfilled state
    }, ms);
  });
}

function getFive(){
  // We're RETURNING the promise. Remember, a promise is a wrapper over our value
  return delay(100).then(function(){ // When the promise is ready,
      return 5; // return the value 5. Promises are all about return values
  })
}
// We _have_ to wrap it like this in the call site, and we can't access the plain value
getFive().then(function(five){
   document.body.innerHTML = five;
});

Basically, instead of returning a value which we can't do because of the concurrency model - we're returning a wrapper for a value that we can unwrap with then. It's like a box you can open with then.

Applying this

This stands the same for your original API call, you can:

function foo() {
    // RETURN the promise
    return fetch("/echo/json").then(function(response){
        return response.json(); // Process it inside the `then`
    });
}

foo().then(function(response){
    // Access the value inside the `then`
})

So this works just as well. We've learned we can't return values from already asynchronous calls, but we can use promises and chain them to perform processing. We now know how to return the response from an asynchronous call.

ES2015 (ES6)

ES6 introduces generators which are functions that can return in the middle and then resume the point they were at. This is typically useful for sequences, for example:

function* foo(){ // Notice the star. This is ES6, so new browsers, Nodes.js, and io.js only
    yield 1;
    yield 2;
    while(true) yield 3;
}

Is a function that returns an iterator over the sequence 1,2,3,3,3,3,.... which can be iterated. While this is interesting on its own and opens room for a lot of possibility, there is one particular interesting case.

If the sequence we're producing is a sequence of actions rather than numbers - we can pause the function whenever an action is yielded and wait for it before we resume the function. So instead of a sequence of numbers, we need a sequence of future values - that is: promises.

This somewhat a tricky, but very powerful trick let’s us write asynchronous code in a synchronous manner. There are several "runners" that do this for you. Writing one is a short few lines of code, but it is beyond the scope of this answer. I'll be using Bluebird's Promise.coroutine here, but there are other wrappers like co or Q.async.

var foo = coroutine(function*(){
    var data = yield fetch("/echo/json"); // Notice the yield
    // The code here only executes _after_ the request is done
    return data.json(); // 'data' is defined
});

This method returns a promise itself, which we can consume from other coroutines. For example:

var main = coroutine(function*(){
   var bar = yield foo(); // Wait our earlier coroutine. It returns a promise
   // The server call is done here, and the code below executes when done
   var baz = yield fetch("/api/users/" + bar.userid); // Depends on foo's result
   console.log(baz); // Runs after both requests are done
});
main();

ES2016 (ES7)

In ES7, this is further standardized. There are several proposals right now, but in all of them you can await promise. This is just "sugar" (nicer syntax) for the ES6 proposal above by adding the async and await keywords. Making the above example:

async function foo(){
    var data = await fetch("/echo/json"); // Notice the await
    // code here only executes _after_ the request is done
    return data.json(); // 'data' is defined
}

It still returns a promise just the same :)

如何从异步电话中返回响应?

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文