同步执行保存在变量中的promise

时间:2018-04-24 10:03:04

标签: javascript promise es6-promise

我起草了一个代码示例,以便更好地理解Promise链接,发现自己对这里发生的事情感到很困惑。

假设我们有两个存储Promises的变量:

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 2');
  }, 1000);
});

然后我们将它们链接起来:

promise1
  .then(data => {
      console.log(data);
      return promise2;
  })
  .then(data => {
      console.log(data);
  });

这两个console.log似乎同时到达,虽然我希望它们之间暂停1秒。如果我创建返回promises并链接它们的函数,行为是相同的:

function firePromise1() {
    return promise1;
} 

function firePromise2() {
    return promise2;
} 

firePromise1()
    .then(data => {
        console.log(data);
        return firePromise2();
    })
   .then(data => {
        console.log(data);
   });

只有当我“在旅途中”创建一个承诺时(无论是在promise链中调用的函数内还是then()块本身),我都会看到promises一个接一个地解决,间隔为1秒:

promise1
    .then(data => {
    console.log(data);
    return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve('promise 2');
          }, 1000);
        });
    })
    .then(data => {
      console.log(data); 
    });

有人可以解释为什么它会这样运作吗?它是关于JS如何初始化变量并以某种方式与“Promise立即执行”(https://hackernoon.com/functional-javascript-resolving-promises-sequentially-7aac18c4431e)这一事实相关联的?我深入研究了不同的资源和文档,但似乎仍然错过了一些重要甚至是显而易见的东西......谢谢!

3 个答案:

答案 0 :(得分:1)

Promise是同步获取未来值(异步任务的结果)的占位符的抽象。在您调用函数时,您将返回一个承诺,您将触发关联的异步任务,而不是在您将.then()链接到promise时。因此,在您定义承诺的那一刻,您几乎已经同时启动了异步任务。你最好不要存储你的承诺,但承诺返回函数需要时调用。

这是一个promise promise函数,它使用普通错误的第一个回调类型异步函数来返回一个promise。

function asyncTask(data){
  return new Promise((v,x) => doAsyncThings(data, (e,r) => e ? x(e) : v(r)));
}

以下是利用递归承诺定序器对promise进行排序的示例。



var sequenceAsync = ([d,...ds]) => d !== void 0 && asyncTask(d).then(v => sequenceAsync(ds)),
    asyncTask     = n => new Promise(v => setTimeout(n => (console.log(n), v()), 1000, n)),
    data          = [1,2,3,4,5];

sequenceAsync(data);




答案 1 :(得分:0)

  

有人可以解释为什么它会这样运作吗?是关于如何JS   初始化变量并以某种方式与“承诺”这一事实相关联   立即执行"

是的,正是因为如此。承诺将在声明后立即执行,因此在您声明promise1时它会自动等待1秒并且promise2相同。如果要在第一个操作完成后等待一秒钟,则必须在then块中声明promise(如上例所示)。通常的做法是拥有返回承诺的函数:

const getSecondPromise = () => new Promise((resolve, reject) => setTimeout(() => resolve('promise 2' ));

然后您可以在第一个承诺的当时调用该函数,并立即执行第二个函数。

答案 2 :(得分:0)

对于涉及声明promise1promise2作为变量的前两个承诺链,即:

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('promise 2');
  }, 1000);
});

当您声明并赋值变量时,赋值运算符的右侧会立即求值,即两个setTimeout函数立即启动。它与承诺“被执行”无关。您可以在console.log("Print me!")个函数内部setTimeout进行测试。

如果您在以下函数中声明了promise,然后创建了一个then()链,那么在promise1和promise2的记录之间会有一秒钟的延迟。

function prom1(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
        resolve('promise 1');
      }, 1000);
    });
}
function prom2(){ 
    return new Promise((resolve, reject) => {
        setTimeout(() => {
        resolve('promise 2');
      }, 1000);
    });
}