Javascript 承诺然后解决得太快

Javascript 承诺然后解决得太快,javascript,es6-promise,Javascript,Es6 Promise,我试图学习js的承诺,但我有点被卡住了。我的目标是在显示加载程序的过程中获取一个图像源(使用replace),因为一些图像尺寸很大。我的问题是它正确地传递了变量,但是“promise.then”在创建src之前运行 下面是代码,我需要src值后跟加载程序隐藏。我知道有更多的方法来实现这一点,但正如前面提到的,我的目标是理解承诺。我还尝试添加一个setTimeout,但再次,承诺解决它太快,添加了一个损坏的图像标志 $(".owlsmaller").on("click", function(){

我试图学习js的承诺,但我有点被卡住了。我的目标是在显示加载程序的过程中获取一个图像源(使用replace),因为一些图像尺寸很大。我的问题是它正确地传递了变量,但是“promise.then”在创建src之前运行

下面是代码,我需要src值后跟加载程序隐藏。我知道有更多的方法来实现这一点,但正如前面提到的,我的目标是理解承诺。我还尝试添加一个setTimeout,但再次,承诺解决它太快,添加了一个损坏的图像标志

$(".owlsmaller").on("click", function(){

    $(".loader").show();

    const promise = new Promise((resolve, reject) => {
      str = $(this).attr("src").replace(/-800x300/gi, '');
        resolve(str);
    });

    promise
        .then((str) => {
            console.log(str);
            $(".mainThumb").attr("src", str);
            $(".mainThumb").attr("srcset", str);
        })
        .then( () => {
            $(".loader").hide();
        });
  });

您的承诺需要等待映像加载。您是否已将replace()的返回值分配给图像的src

const promise = new Promise((resolve, reject) => {
  $(this).on("load", resolve)
         .on("error", reject)
         .attr("src", (index, attr) => attr.replace(/-800x300/gi, ''));
});

TLDR您的承诺将立即得到解决(*1),因为没有异步代码在运行。你的方法应该有所不同

再解释一下

你对承诺的作用有误解。承诺允许您等待异步代码的解析,但将同步代码放在承诺的主体内并不能使该代码异步

编辑:根据@juan mendez的评论,我将澄清:promise主体内的代码正常运行(同步),并在调用promise构造函数后立即执行。事实上,Promise构造函数获取的函数参数名为
executor
,它会立即执行!。最终被延迟的是作为参数传递给
then
方法的任何函数的调用,或者在
then
调用之后链接的任何函数的调用

Promise构造函数旨在让您运行一些异步函数(如get请求),该函数通常为您提供一个回调,以便对该调用的结果进行操作。然后您可以在回调中调用
resolve

您调用的jQuery函数
$
attr
是同步的,因此不需要承诺。事实上,您放置resolve调用甚至不关心
$
attr
是否是异步的,因为它是紧跟在回调之后放置的,而不是放在回调或类似的内容中(当然,没有回调,因为没有异步性)


*(1) 在所有同步代码完成运行后立即执行。

您没有尝试等待映像加载,您只是有一个硬编码的超时,这样映像可能会被提取,也可能不会被提取。你的问题是什么?不知道为什么在这种情况下会使用承诺。是否要等待映像加载?我的目标是使用Promission中的str变量更改另一个映像的src。使用Promission更改非异步操作的字符串似乎很奇怪。代码将运行得如此之快,您将看不到正在加载的元素。在代码中没有等待图像加载的等待。@epascarello我假设是一个图像,为什么它不能解析或拒绝?在编辑之后,这仍然不是正确的。这不是jQuery的工作方式您不能为
$(this).attr(“src”)
表达式赋值。是的,很抱歉,十年左右没有编写jQuery:p这里有链接和变量来存储内容。承诺确实会使代码异步。尝试
Promise.resolve()。然后(=>.console.log(“来自Promise”);console.log(“在Promise之后”)
如果谈论
,那么这是正确的。然后
方法,但不是Promise声明中的代码。马上执行。
.then
的解析是微任务队列中结束的部分(因此,延迟到所有同步代码完成为止)。