Javascript承诺中的动态链接

Ram*_*jay 20 javascript promise

我怎么能在Javascript Promises中执行动态链接,所有的时间我只看到了对例如的调用的硬编码.(promise).then(request/functionName).then(request/functionName)

wuh*_*her 46

给定一个都返回promise的数组函数,您可以使用reduce()它们顺序运行它们:

var myAsyncFuncs = [
    function (val) {return Promise.resolve(val + 1);},
    function (val) {return Promise.resolve(val + 2);},
    function (val) {return Promise.resolve(val + 3);},
];

myAsyncFuncs.reduce(function (prev, curr) {
    return prev.then(curr);
}, Promise.resolve(1))
.then(function (result) {
    console.log('RESULT is ' + result);  // prints "RESULT is 7"
});
Run Code Online (Sandbox Code Playgroud)

上面的示例使用ES6 Promises,但所有promise库都具有类似的功能.

此外,创建promise返回函数数组通常是一个很好的使用方法map().例如:

myNewOrmModels.map(function (model) {
    return model.save.bind(model);
}).reduce(function (prev, curr) {
    return prev.then(curr);
}, Promise.resolve())
.then(function (result) {
    console.log('DONE saving');
});
Run Code Online (Sandbox Code Playgroud)


Jas*_*zak 7

一种选择是利用对象的属性以及通过字符串调用它们的能力.

在这里写了一个小样本并在下面发布.

我的想法是你有一套你希望在某个命名空间或对象中运行的函数,就像我在'myNamespace'中所做的那样:

myNamespace = {
    "A": function() {return "A Function";},
    "B": function() {return "B Function";},
    "C": function() {return "C Function";}
}
Run Code Online (Sandbox Code Playgroud)

那么你的主要承诺将以某种方式(通过输入,ajax,提示等)运行,你将得到你想要运行的函数的字符串值,这在运行时才知道:

我的主要承诺使用提示来获取用户的来信:

var answer = prompt('Starting.  Please pick a letter: A,B,C');
        if(myNamespace[answer] === undefined)
        {
            alert("Invalid choice!");
            reject("Invalid choice of: " + answer);
        }
        else
        {
            resolve(answer);
        }
Run Code Online (Sandbox Code Playgroud)

在接下来的'then'中,我使用该值(通过resolve函数传递)来调用函数:

.then(function(response) {
        funcToRun = myNamespace[response]();})
Run Code Online (Sandbox Code Playgroud)

最后,我输出到html我的动态函数调用的结果,我使用一些递归的乐趣,使它更具交互性,并证明它是动态的:

.then(function(){
        document.getElementById('result').innerHTML = funcToRun;})
    .then(function(){
        if(prompt("Run Again? (YES/NO)")==="YES")
        {
            doWork();
        }
    });
Run Code Online (Sandbox Code Playgroud)

myNamespace = {
    "A": function() {return "A Function";},
    "B": function() {return "B Function";},
    "C": function() {return "C Function";}
}

function doWork()
{
    var funcToRun;
    
    new Promise(function(resolve,reject) {
        var answer = prompt('Starting.  Please pick a letter: A,B,C');
        if(myNamespace[answer] === undefined)
        {
            alert("Invalid choice!");
            reject("Invalid choice of: " + answer);
        }
        else
        {
            resolve(answer);
        }
    })
    .then(function(response) {
        funcToRun = myNamespace[response]();})
    .then(function(){
        document.getElementById('result').innerHTML = funcToRun;})
    .then(function(){
        if(prompt("Run Again? (YES/NO)")==="YES")
        {
            doWork();
        }
    });
}

doWork();
Run Code Online (Sandbox Code Playgroud)
<div id="result"></div>
Run Code Online (Sandbox Code Playgroud)


Tra*_*man 6

由于承诺解包,只需继续添加then语句,它将继续链接在一起

function asyncSeries(fns) {
  return fns.reduce(function(p, fn) {
    return p.then(fn);
  }, Promise.resolve());
}
Run Code Online (Sandbox Code Playgroud)

递归是一个非常酷的方式来做它:)

function countTo(n, sleepTime) {
  return _count(1);

  function _count(current) {
    if (current > n) {
      return Promise.resolve();
    }

    return new Promise(function(resolve, reject) {
      console.info(current);
      setTimeout(function() {
        resolve(_count(current + 1));
      }, sleepTime);
    });
  }
}
Run Code Online (Sandbox Code Playgroud)


all*_*kim 6

这是ES7的方式。

假设您在一个数组中定义了多个 Promise。

  var funcs = [
    _ => new Promise(res => setTimeout(_ => res("1"), 1000)),
    _ => new Promise(res => setTimeout(_ => res("2"), 1000))
  }
Run Code Online (Sandbox Code Playgroud)

你想这样打电话。

 chainPromises(funcs).then(result => console.log(result));
Run Code Online (Sandbox Code Playgroud)

您可以使用asyncandawait来达到此目的。

  async function chainPromises(promises) {
    for (let promise of promises) {  // must be for (.. of ..)
      await promise();
    }
  }
Run Code Online (Sandbox Code Playgroud)

这将按顺序(一个接一个)执行给定的函数,而不是并行执行。参数promises是一个函数数组,返回Promise.

笨蛋: http: //plnkr.co/edit/UP0rhD?p= preview