我起草了一个代码示例,以便更好地理解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)这一事实相关联的?我深入研究了不同的资源和文档,但似乎仍然错过了一些重要甚至是显而易见的东西......谢谢!
答案 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)
对于涉及声明promise1
和promise2
作为变量的前两个承诺链,即:
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);
});
}