承诺链中的承诺之间的延迟

For*_*vin 12 javascript delay promise ecmascript-6 es6-promise

假设我使用以下代码来运行一系列的promises:

let paramerterArr = ['a','b','c','d','e','f']
parameterArr.reduce(function(promise, item) {
  return promise.then(function(result) {
    return mySpecialFunction(item);
  })
}, Promise.resolve())
Run Code Online (Sandbox Code Playgroud)

代码只是调用mySpecialFunction(它返回一个promise),等待解析的promise,然后再次调用mySpecialFunction等等.因此,对于数组中的每个元素,按正确的顺序调用该函数一次.

我怎样才能确保每次通话之间至少有50毫秒的延迟mySpecialFunction(item)

重要的是承诺以正确的顺序执行,执行时间mySpecialFunction每次都不同.

我想同步睡眠会起作用,但我不打算在一个单独的线程中运行这个代码,因此它会在浏览器中引起恼人的ui冻结.

我不确定是否可以以某种方式使用setTimer.我的意思是我不能拖延承诺的回归.

Ben*_*aum 18

答案很好,但他们等待的时间太长,因为无论实际操作是否已超过50毫秒,所有答案都会等待.

你可以用Promise.all它.

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
let paramerterArr = ['a','b','c','d','e','f']
parameterArr.reduce(function(promise, item) {
  return promise.then(function(result) {
    return Promise.all([delay(50), mySpecialFunction(item)]);
  })
}, Promise.resolve())
Run Code Online (Sandbox Code Playgroud)

  • 打败我 37 秒 :-) (2认同)

jfr*_*d00 5

我称之为一个非常方便的实用函数delay()

function delay(t, val) {
    return new Promise(function(resolve) {
        if (t <= 0) {
            resolve(val);
        } else {
            setTimeout(resolve.bind(null, val), t);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在承诺链中使用它,如下所示:

let paramerterArr = ['a','b','c','d','e','f']
parameterArr.reduce(function(promise, item, index) {
  return promise.then(function(result) {
    // no delay on first iteration
    var delayT = index ? 50 : 0;
    return delay(delayT, item).then(mySpecialFunction);
  })
}, Promise.resolve());
Run Code Online (Sandbox Code Playgroud)

您还可以创建一个小实用函数来执行带有可选延迟的顺序迭代:

// delayT is optional (defaults to 0)
function iterateSerialAsync(array, delayT, fn) {
    if (!fn) {
        fn = delayT;
        delayT = 0;
    }
    array.reduce(function(p, item, index) {
        return p.then(function() {
            // no delay on first iteration
            if (index === 0) delayT = 0;
            return delay(delayT, item).then(fn)
        });
    }, Promise.resolve());
}
Run Code Online (Sandbox Code Playgroud)

然后你会像这样使用它:

iterateSerialAsync(paramerterArr, 50, mySpecialFunction).then(function(finalVal) {
    // all done here
});
Run Code Online (Sandbox Code Playgroud)